Actually it's probably better, as it prevents ambiguity about which predicates 'class-instance' should meet. Unlike 'class-instance', the expression '(class-instance)' starts with no predicates, so making '(list? (class-instance))' true won't disrupt anything else. Thus, you can be explicit about when it should behave as a class instance and when it should behave as a list.
On Sat, Oct 4, 2014 at 9:50 AM, Matthew Butterick <m...@mbtype.com> wrote: > I see your point. As a workaround, I suppose it's just as good to combine > these ideas and use `prop:procedure` to hook into the `get-list` method. > Then, instead of using 'class-instance' as a list, I can use > '(class-instance)', > and things like (member val (class-instance)) and (map proc > (class-instance)) will work as expected (= operating on the list inside the > class instance). > > > > On Sat, Oct 4, 2014 at 8:13 AM, Robby Findler <ro...@eecs.northwestern.edu > > wrote: > >> There is no prop:list like that. >> >> Adding more prop:* features (like prop:list) has implications for code >> that you cooperate with. In particular, when you get something that >> answers #t to list?, then you can rest assured that calling 'car' or >> it is a very simple operation (doesn't invoke unknown code, involves >> just a pointer dereference and some simple checks in the machine, >> etc). If we had a prop:list, then you wouldn't know those things and >> thus you might have to treat simple list iterations with the same care >> that you treat calling into unknown code (like it might grab a >> continuation and return to you later etc). >> >> That said, I do think that our integration of generic operations and >> our standard library deserves some more care and perhaps redesign to >> make things hang together better. As it stands, we have some >> conveniences, but they are limited by backwards compatibility concerns >> (like the one in the previous paragraph). I have heard that some are >> considering this as part of "racket2" but I don't know how far along >> those plans are. >> >> Robby >> >> >> >> On Sat, Oct 4, 2014 at 10:01 AM, Matthew Butterick <m...@mbtype.com> wrote: >> > Thank you. The `prop:procedure` works as hoped, in that the class >> instance >> > becomes usable in any form that takes a procedure (including things like >> > map). >> > >> > The `prop:sequence` also works, but … what it seems I really want is >> > `prop:list`, which AFAICT doesn't exist (?) >> > >> > The class I'm making is basically a list wrapped with some state. So in >> > terms of the class interface, it would be very convenient to allow a >> class >> > instance to be used anywhere a list is used. >> > >> > The problem with `prop:sequence` is that now I have to use the special >> > sequence versions of list functions, or convert to a list explicitly >> with >> > `sequence->list`. In terms of class interface, this isn't an improvement >> > over just using a method like (send class-instance get-list). >> > >> > >> > >> > On Thu, Oct 2, 2014 at 7:43 PM, Alexander D. Knauth < >> alexan...@knauth.org> >> > wrote: >> >> >> >> I don’t know if you can do it with generic interfaces (as in >> >> racket/generic), >> >> but you can make classes whose instances have struct-type properties >> such >> >> as prop:procedure and prop:sequence >> >> (using interfaces as in racket/class, not racket/generic) >> >> >> >> #lang racket >> >> >> >> (define proc<%> >> >> (interface* () >> >> ([prop:procedure >> >> (lambda (this . args) >> >> (send/apply this proc args))]) >> >> proc)) >> >> >> >> (define proc% >> >> (class* object% (proc<%>) >> >> (super-new) >> >> (define/public (proc x) >> >> (displayln "this is the proc method of proc%") >> >> x))) >> >> >> >> (define seq<%> >> >> (interface* () >> >> ([prop:sequence >> >> (lambda (this) >> >> (send this get-sequence))]) >> >> get-sequence)) >> >> >> >> (define seq% >> >> (class* object% (seq<%>) >> >> (super-new) >> >> (define/public (get-sequence) >> >> (list 1 2 3)))) >> >> >> >> > (define p (new proc%)) >> >> > (p 1) >> >> this is the proc method of proc% >> >> 1 >> >> > (define s (new seq%)) >> >> > (sequence-for-each displayln s) >> >> 1 >> >> 2 >> >> 3 >> >> >> >> On Oct 2, 2014, at 6:21 PM, Matthew Butterick <m...@mbtype.com> wrote: >> >> >> >> What's the best approach to: >> >> >> >> + defining a class whose instances can be used as procedures? >> >> >> >> (define ci (new proc-class%)) >> >> (ci arg arg2 ... ) >> >> >> >> + ... whose instances can be used as lists (or at least support direct >> >> iteration?) >> >> >> >> (define li (new listish-class%)) >> >> (for-each displayln li) >> >> (map ci li) >> >> >> >> My intuition is "implement a generic interface..." But then it gets >> hazy. >> >> >> >> >> >> >> >> >> >> ____________________ >> >> Racket Users list: >> >> http://lists.racket-lang.org/users >> >> >> >> >> > >> > >> > ____________________ >> > Racket Users list: >> > http://lists.racket-lang.org/users >> > >> > >
____________________ Racket Users list: http://lists.racket-lang.org/users