<div dir="ltr">I&#39;m not sure what TR is really doing here yet, but my intention was to suggest that the kons struct can have an extra (mutable) field. When LST/C encounters (in a positive position) a kons, then it bangs some representation of A into the extra field. When it sees a kons struct in a negative position, it can look in that field and compare it with the A it has. If this test fails, then I think the expensive test is doomed, but maybe not always, I&#39;m not sure (guess subtyping could make it not be doomed and maybe other things).<div>
<br></div><div style>Does that make sense?</div><div><br></div><div>Robby</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 6, 2013 at 3:13 PM, Robby Findler <span dir="ltr">&lt;<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This has a non-chaperone contract being used in a struct/c, I think?<div><br></div><div>(FST (LST 1 2 3)) =&gt; struct/dc: expected chaperone contracts, but field a has #&lt;barrier-contract&gt;</div>
<span class="HOEnZb"><font color="#888888"><div><br>
</div><div>Robby</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 6, 2013 at 2:40 PM, Sam Tobin-Hochstadt <span dir="ltr">&lt;<a href="mailto:samth@ccs.neu.edu" target="_blank">samth@ccs.neu.edu</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>On Sun, Jan 6, 2013 at 3:23 PM, Robby Findler<br>
&lt;<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>&gt; wrote:<br>
&gt; On Sun, Jan 6, 2013 at 2:18 PM, Sam Tobin-Hochstadt &lt;<a href="mailto:samth@ccs.neu.edu" target="_blank">samth@ccs.neu.edu</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; The boundaries have the information; that&#39;s how the contracts got<br>
&gt;&gt; &gt; inserted<br>
&gt;&gt; &gt; in the first place.<br>
&gt;&gt;<br>
&gt;&gt; No, the contracts are parametric contracts using `parametric-&gt;/c`, and<br>
&gt;&gt; thus don&#39;t have any information about the types used at all.<br>
&gt;<br>
&gt;<br>
&gt; I don&#39;t see why you can&#39;t tag them when something at a boundary and then<br>
&gt; check that something at another boundary instead of doing some deep check.<br>
<br>
</div></div>The problem is that I don&#39;t know what to tag them *with*.<br>
<br>
Consider the following program:<br>
<br>
#lang racket<br>
<br>
(struct kons (a d))<br>
(struct mt ())<br>
(define MT (mt))<br>
(define (FST v)<br>
  (when (eq? MT v) (error &#39;empty))<br>
  (kons-a v))<br>
(define (RST v)<br>
  (when (eq? MT v) (error &#39;empty))<br>
  (kons-d v))<br>
(define (LST . x)<br>
  (if (empty? x)<br>
      MT<br>
      (kons (first x) (apply LST (rest x)))))<br>
(define (LST/C elem/c)<br>
  (define C (recursive-contract<br>
             (or/c (λ (v) (eq? v MT))<br>
                   (struct/c kons elem/c C))))<br>
  C)<br>
(provide/contract<br>
 [LST (parametric-&gt;/c (A) (-&gt;* () #:rest A (LST/C A)))]<br>
 [FST (parametric-&gt;/c (A) (-&gt; (LST/C A) A))]<br>
 [RST (parametric-&gt;/c (A) (-&gt; (LST/C A) (LST/C A)))])<br>
<br>
This is the essence of Neil&#39;s polymorphic list program, as implemented<br>
by Typed Racket. I don&#39;t know how to change those contracts to not be<br>
really expensive, because I can&#39;t pick the instantiation of A at<br>
runtime to tag the structure instances with.<br>
<span><font color="#888888"><br>
Sam<br>
</font></span></blockquote></div><br></div>
</div></div></blockquote></div><br></div>