[ENH] Message lookup-failure overrides

Brian Rice water at tunes.org
Tue Mar 21 16:20:29 PST 2006


Quickie hack example of this usage:

Slate 1> ensureNamespace: #Integers.
(traitsWindow)
Slate 2> _ at Integers didNotUnderstand: msg at: idx [(Integer readFrom:  
msg selector) ifNotNilDo: [| :i | [i]]].
[didNotUnderstand:at:]
Slate 3> #4 sendWith: Integers.
4

"Integers 4" is not valid in Slate grammar right now, hence the  
sendWith:, but that'd be the idea of this object. It's the same with  
any other literal. This can be changed, but it'd push Slate towards a  
Forth-like (aka "concatenative") grammar.

If we did this, then a LOT more would be permitted in Slate grammar.  
For example, "(some Expression) ( foo bar baz )" would evaluate the  
first expression which would then receive #( and then result in  
something that receives #foo, #bar, #baz, #), and so on.

Honestly, I don't want to do that unless it's optimized-for in some  
way using pre-hoc programmatics using Map meta-objects than with DNU.  
Just to give an idea, every DNU-based setup requires a full lookup  
through the whole delegation tree before DNU is signaled by the VM  
and then handled, for each such send. So in order to make this a  
normal thing for Slate, it would have to be supported pre-lookup  
instead of post-lookup.

However, if enough people think this is cool and worth adding, I'll  
have second thoughts or at least put more energy into it. Slate needs  
a dynamic inlining compiler, more urgently, though, so don't push too  
hard unless you don't care about that.

In any case, the rationale for this kind of syntax extension is to  
give us a more flexible way to make structures of things. Doing this  
at the grammar / text-syntax level is troublesome, but lately I'm  
getting more and more fed up with Smalltalk-80 syntax limitations WRT  
Lisp or Forth.  (Slate's first design had that kind of grammar but  
went off the deep end and wasn't easy enough to read or write, and  
was scrapped for the PMD + Smalltalk-80-ish syntax idea instead.)

On Mar 21, 2006, at 12:06 AM, Brian Rice wrote:

> Similar to Smalltalk's doesNotUnderstand: or Ruby's method_missing 
> (), in the sense that they can be used to override and delegate  
> behavior, I have added hooks to override the handling  
> MethodNotFound per argument in the given message-send.
>
> MethodNotFound is raised by "#selector notFoundOn: {args...}" by  
> the VM and therefore does not allow PMD-based overrides.
>
> The new hook is #didNotUnderstand:at: taking a Message object and  
> the argument position that the main object played. The way it works  
> is easiest to show with the actual code from condition-epilogue.slate:
>
> selector@(Symbol traits) notFoundOn: arguments &optionals: optionals
> "Query the arguments for an abnormal handler before signalling  
> MethodNotFound."
> [| message |
>   message: (Message sending: selector to: arguments &optionals:  
> optionals).
>   arguments doWithIndex:
>     [| :arg :index | (arg didNotUnderstand: message at: index)  
> ifNotNilDo:
>       [| :result | ^ result do]].
>   (MethodNotFound new `>> [message: message. ]) signal
> ].
>
> First, the #notFoundOn: signal-handler method creates a Message  
> object. Then it calls #didNotUnderstand:at: on each argument in  
> turn (left-to-right precedence). If the result of sending it  
> returns Nil, it continues. Otherwise, it assumes that it returns a  
> 0-argument block which it then evaluates and returns, rather than  
> continuing on to check further arguments or signal MethodNotFound.
>
> The convention of Nil-vs.-0-arg-Method is arbitrary, mostly chosen  
> for genericity. The other possibilities that occurred to me were:
>
> 1) Return a value, anything but Nil. The 0-arg block convention  
> allows returning Nil ultimately so it's a little more generic.
>
> 2) Return a Method with the correct arity and applying it to the  
> arguments as well as the optionals. This seemed too constricting,  
> plus the #didNotUnderstand:at: handler already receives that  
> structure so it could do that itself.
>
> The 0-arg Method returned will likely be a Closure so it has a  
> little extra overhead. Anyway, for those who are interested in this  
> kind of thing, make yourself heard if there's something I'm missing  
> as a use-case or whatever. Sometime, I'll get around to writing  
> some types that use this, but they'll be the ones that need  
> something more powerful than regular delegation.
>
> Anyway, this solution is notable in that multiple-dispatch systems  
> generally don't allow this kind of override - this is a kind of  
> compromise that mostly honors the philosophy of multiple dispatch.  
> I will admit that DNU-style usage of Smalltalk is usually not good  
> practice (since DNU overrides do not compose safely), but there are  
> valid cases for its usage.
>
> My "blue sky" alternative is the ability to override an object's  
> Map with some regular Slate object, but this is not yet feasible.

--
-Brian
http://tunes.org/~water/brice.vcf

-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : /archives/slate/attachments/20060321/85e954f5/PGP.pgp


More information about the Slate mailing list