I'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'm not sure (guess subtyping could make it not be doomed and maybe other things).
Does that make sense? Robby On Sun, Jan 6, 2013 at 3:13 PM, Robby Findler <ro...@eecs.northwestern.edu>wrote: > This has a non-chaperone contract being used in a struct/c, I think? > > (FST (LST 1 2 3)) => struct/dc: expected chaperone contracts, but field a > has #<barrier-contract> > > Robby > > > On Sun, Jan 6, 2013 at 2:40 PM, Sam Tobin-Hochstadt <sa...@ccs.neu.edu>wrote: > >> On Sun, Jan 6, 2013 at 3:23 PM, Robby Findler >> <ro...@eecs.northwestern.edu> wrote: >> > On Sun, Jan 6, 2013 at 2:18 PM, Sam Tobin-Hochstadt <sa...@ccs.neu.edu> >> > wrote: >> >> >> >> > The boundaries have the information; that's how the contracts got >> >> > inserted >> >> > in the first place. >> >> >> >> No, the contracts are parametric contracts using `parametric->/c`, and >> >> thus don't have any information about the types used at all. >> > >> > >> > I don't see why you can't tag them when something at a boundary and then >> > check that something at another boundary instead of doing some deep >> check. >> >> The problem is that I don't know what to tag them *with*. >> >> Consider the following program: >> >> #lang racket >> >> (struct kons (a d)) >> (struct mt ()) >> (define MT (mt)) >> (define (FST v) >> (when (eq? MT v) (error 'empty)) >> (kons-a v)) >> (define (RST v) >> (when (eq? MT v) (error 'empty)) >> (kons-d v)) >> (define (LST . x) >> (if (empty? x) >> MT >> (kons (first x) (apply LST (rest x))))) >> (define (LST/C elem/c) >> (define C (recursive-contract >> (or/c (λ (v) (eq? v MT)) >> (struct/c kons elem/c C)))) >> C) >> (provide/contract >> [LST (parametric->/c (A) (->* () #:rest A (LST/C A)))] >> [FST (parametric->/c (A) (-> (LST/C A) A))] >> [RST (parametric->/c (A) (-> (LST/C A) (LST/C A)))]) >> >> This is the essence of Neil's polymorphic list program, as implemented >> by Typed Racket. I don't know how to change those contracts to not be >> really expensive, because I can't pick the instantiation of A at >> runtime to tag the structure instances with. >> >> Sam >> > >
_________________________ Racket Developers list: http://lists.racket-lang.org/dev