Last night I was working on implementing binary messages for my Self.js project. The issue with binary message sends is that the right hand side is effectively part of the message. If you think of the simple case:
1 + 2
The object 1 is receiving a message + and that product then receiving the message 2:
((1 +) 2)
Or the + message holds an implicit parameter such that :
For sake of simplicity I went down the later, as it posed an interesting question:
Now I know it is easy to generate a function object to evaluate a partial application. Most of Self.js relies on the production of closure functions from dynamic sources. The interesting question was did the language implementers build their engine such that:
1'+'(2) == 3
So far the answer is "yes on Safari". I started off this exploration with this code:
Number.does('+', function(y) )
The 'does' function merely walks the argument list assigning slots in the object's prototype. The name was inspired by create does> in Forth, but is just a nice readable way to extend a base prototype. It turns out that this is all that is needed to get the message send to work.
But that's not all! We need our Lisp like structure to evaluate the representation:
Array.does('eval', function() )
This has the super awesome ability to turn an array of strings into a self evaluating Array.
'1 + 2'.split(/\\s+/).eval()
Will transform the string into an array:
Which will then eval '1' to 1 and invoke
Via apply which will call
Where this === 1 and y === '2'
And while this looks like a long way to go to add two numbers, it shows how one can represent program in Json, and perform dynamic dispatch to functions which "fix" builtin behavior.
I have gone on to implementing a whole host of infix operators.
Next step partial application and macros :)