>>34
but is it the name of a method on w or is it a value to be supplied (where and how should it be evaluated?
This is a failure to specify how you wanted messages to be represented. Since we had been talking about currying, I had assumed that a message was some first class value that was dispatched upon to return either another value and that in your examples 'message' could conceivably be any legal expression of the language that returned a message.
Since all objects can be assumed to be happy to receive more messages, we can't simply consider whether w is a closure wanting more arguments since it's still an object and all objects appear the same in this regard (and arguments are being supplied as messages.)
True, this was the decision you made when you decided to give message passing the same semantics as function application.
Going along, suppose we decide we'll take whatever we can get. If x is a valid message (i.e. w contains a slot/property/member named 'x'), it will be treated as such. If not, it will be evaluated in the caller before being passed on.
Yuck
The problem of ambiguity arises when x qualifies as both. You can assign priority (probably to the caller), but you may want to use the alternative (eg. in the callee.) A simple '.' prefix might specify that x is intended as a message name: w .x y
I see the problem, you wanted to treat a message as any other identifier. That was always going to bite you. Use
anything else: a separate type, strings, numbers, lists, vectors, functions; just not identifiers, since you'll get fucked over by your scoping rules.
Which is precisely regular curried syntax with functions
Which is what you wanted, right?
-- Example
(define (make-object x y)
(letrec ((foo x)
(bar y)
(dispatch
(lambda (disp)
(case disp
;; assuming symbols are messages, they are treated normally
((foo) foo) ;field accessors
((bar) bar)
((set-bar!) (lambda (val)
(set! bar val)))
(else ; if the "message" has a different type
(cond ((string? disp) ; a string can be a message too
(dispatch (string->symbol disp)))
((list? disp) ; if a message is a list, dispatch on each
(map dispatch disp))
((vector? disp) ; ditto for vectors
(vector-map dispatch disp))
(else ; or whatever
(error "Can't dispatch on message" disp))))))))
dispatch))
;Value: make-object
(define o (make-object 2 3))
;Value: o
(o 'foo)
;Value: 2
(o 'bar)
;Value: 3
(o 'set-bar!)
;Value 19: #[compound-procedure 19]
((o 'set-bar!) 89)
;Value: 3
(o 'bar)
;Value: 89
(o '(foo bar))
;Value 20: (2 89)
(let ((v (o '#(bar set-bar!))))
((vector-ref v 1) 80)
`(before ,(vector-ref v 0) after ,(o 'bar)))
;Value 21: (before 89 after 80)
(o 'bar)
;Value: 80
((o 'set-bar!) 89)
;Value: 80