[plt-scheme] first-class methods
At Sun, 28 Nov 2004 14:02:39 -0500, Dave Herman wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> Someone may have explained this to me once, but I can't remember. Why
> can't public methods be passed as first-class values inside the class
> definition?
Methods are not functions (they're not really independent values at
all, in fact). Another way to think of this is that methods are stored
with the class, not the instance. An object is a record of n+1 slots:
one per each of the n fields and then one with a reference to the class
definition. Method invocation looks in that special field, calls the
corresponding closure and passes along the object as the first
argument.
> (define my-class%
> (class object%
> (public purple? foo)
> (define (purple? x)
> (eq? x 'purple))
> (define (foo ls)
> (filter purple? ls))
> (super-new)))
>
> *** class: misuse of method (not in application) in: purple?
>
> (If you don't make purple? public, this works.)
This is a bit of a subtle point. If you write:
(define purple? ...)
with no annotation, it becomes a field -- it's not a method anymore.
You might think that by dropping the public annotation you're getting a
private method, but you're not. You have to add a private annotation to
get a private method.
This is, imo, one of the most confusing parts of our class system. I've
discussed various things with Matthew to try to make this work better,
but we've not found something that we both liked (for various reasons)
so we've left it alone. Perhaps it's time to try again.
> It looks to me like you could make this work by having method
> declarations expand both to their current implementation and to an
> identifier macro that expands purple? in argument position to (lambda
> args (apply purple? args)). Why wouldn't this work?
That would work, but would introduce a surprising performance penalty.
Better to make people write the lambda themselves, imo.
Robby