Thursday, April 16, 2009

Lisp without parentheses

So apparently, every lisp newcomer and their dogs has had the fabulous idea of making a version of Lisp that uses indentation instead of the derided parentheses.

The most common proposal I've seen is to make each line with a deeper level of indentation be a new form.

(0 (1 2))
  1 2

Simple enough. The problem is that the idea breaks when we have a form that looks like (0 1 (2 3) 4 5 (6 7)) or (if condition some-long-form another-long-form). The first breaks because once you indent, there's no syntax to close the current form and return to the parent, since outdenting requires moving to a new line, which closes both forms.

The second form is more subtle: in Algol-like languages, you'd normally some-long-form on a new line and indented. We can't do that with the lisp-without-parens proposal unless we add another symbol to escape line feeds or something like that.

if (foo bar) \
  do-something \

That just looks plain stupid. Let's scratch that.

Another idea would be to make outdenting return to the parent form, i.e. a line feed does not close a form.

(0 1 (2 3) 4 5 (6 7))

0 1
  2 3
4 5
  6 7

(if condition some-long-form another-long-form)

if condition

Bla. Looks dumb and we now need something to denote when a form closes and a new one opens.

(if condition (+ 1 2) (+ 2 3))

if condition
  + 1 2
  + 2 3

Or something equally bizarre. Scratch.

Ok, let's stop with the toying around a bit

In case you haven't noticed the pattern, the problem here is that even though regular lisp has two pieces of syntax (open-parens and close-parens), and python-like syntax has three (line feed, indent and outdent), indent and outdent can't always be written out (e.g. in the last example they cancel out and thus we need a fourth symbol to go around that edge case).

So can Lisp without parentheses work without bolting on weird characters to make edge cases work? I don't see how.


  1. Dave Moon's no newcomer. His PLOT is Lisp-like, but uses Python-style indentation for syntax. Check his ILC2009 presentation for more info.

  2. Do you have a link to it? I suspect I have seen it somewhere, but can't quite remember if that's what I saw.

  3. Actually I found it:

    It was an interesting piece, but it didn't seem to talk as much about strange lispy syntax edge cases as it did about its macro system. I was more interested in figuring out if there was a implementation-related limitations to whitespace-based lisp.

    For a macro system, I was thinking of a somewhat similar idea as PLOT of having values be functions of operators (actually more like macros that operate on primitive types). Then forms like 1 + 2 would be somewhat equivalent to something like 1(&add, 2) if that was possible in C.