[ENH] Message lookup-failure overrides

Brian Rice water at tunes.org
Tue Mar 21 17:09:59 PST 2006


Hm, in how many ways can I state that this interests me and yet deny  
that I want to do it? :P

So, consider this flip-flopping email stupid, and I'll take a look at  
removing this grammatical restriction from the Slate Parser.

End result: in such cases, you'll get MethodNotFound at run-time  
rather than a Lexer error at compile-time. If possible, I'll make  
this a switchable mode.

Yell if you don't like the idea or think I'm too obsessed with it.

On Mar 21, 2006, at 4:20 PM, Brian Rice wrote:

> 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/c2b7fb63/PGP.pgp


More information about the Slate mailing list