Wednesday, May 25, 2011

Alternative s-expression syntax for Soy Lisp

Soy is the name of my lisp dialect (previously called lisphp, and before that phlisp). This is quite a radical departure from standard lisp s-expression but not so far as to, say have infix notation or "sweet expressions". Rather this is a simple inverse of s-expression e.g.:

(if (predicate arg1 arg2)
(thenFunc arg2)
(elseFunc arg3))

Becomes:

if(predicate(arg1 arg2)
thenFunc(arg2)
elseFunc(arg3))

Your first question should be, "but wait! what about homoiconicity and the ability to have quasiquote macro definitions!?". I'm glad you asked, I have two proposals. 1) allow for a s-expression macro syntax, 2) allow for quasiquote to start with an atom:

defmacro(eat-apple person number-of-apples
`person-eat(,person 'apple ,number-of-apples))

You may have noticed the other drawback with this syntax is that it makes having macros which handle sublists a tad more difficult. As any atom followed by (, applies the atom to the arguments inside of the parens. This can be resolved by using rest args for forms which anticipate the last expression to be treated as a lambda. Also Soy allows for [ | ] lambda forms and { } vector/dicts. So it is also possible that would resolve any ambiguities.

One of my major ambitions with this is to have a very simple syntax for exploring alternative object models, similar to my previous post about an alternative object model for javascript.

;simple keyword selector
some-object(set-first-name: 'peter and-last-name: 'jenkum)
;chaining
some-object(some-keyword: arg1 selector: arg2)
(chained-selector: arg3 takes-closure: [ a | a(message: arg4)])
(another-chained-selector: [_(anon-var)])

I really dig how close this comes to snythesizing what I love about smalltalk w/ lisp w/o really forsaking either.

One of the real "wins" with this is when you have function returning functions .. n you don't end up w/ a massive amount of nesting.

(def adder [x | [y | [z | + x y z]]])
(((adder 6) 7) 8)

def(adder [x | [y | [z | +(x y z)]]])
adder(6)(7)(8)

I think the latter reads in a much more obvious "left to right" fashion.

No comments: