David A. Wheeler's Blog

Thu, 06 Dec 2007

Readable s-expressions (sweet-expressions) draft 0.2 for Lisp-like languages

Back in 2006 I posted my basic ideas about “sweet-expressions”. Lisp-based programming languages normally represent programs as s-expressions, and though they are regular, most people find them hard to read. I hope to create an alternative to s-expressions that have their advantages, and not their disadvantages. You can see more at my readable Lisp page. I’ve gotten lots of feedback, based on both my prototype of the idea, as well as on the mailing list discussing it.

I’ve just posted a a draft of version 0.2 of sweet-expressions. This takes that feedback into account, in particular, it’s now much more backwards-compatible. There’s still a big question about whether or not infix should be a default; see the page for more details.

Here are the improvements over version 0.1:

  1. This version is much more compatible with existing Lisp code. The big change is that an unprefixed “(” immediately calls the underlying s-expression reader. This way, people can quietly replace their readers with a sweet-reader, without harming most existing code. In fact, many implementations could quietly switch to a sweet-reader and users might not notice until they use the new features. Instead of using (…), this uses {..} and […] for grouping expressions without disabling sweet-expressions.
  2. It can work more cleanly with macros that provide infix precedence (for those who want precedence rules).
  3. It extends version 0.1’s “name-prefixing” into “term-prefixing”. This is not only more general, it also makes certain kinds of functional programming much more pleasant.
  4. It adds syntax for the common case of accessing maps (such as indexed or associative arrays) - now a[j] is translated into (bracketaccess a j).
  5. Infix default supports arbitrarily-spelled infix operators, and it automatically accepts “and” and “or”.

Here’s an example of (ugly) s-expressions:

 (defun factorial (n)
   (if (<= n 1)
       1
       (* n (factorial (- n 1)))))

Here’s sweet-expressions version 0.1:

 defun factorial (n)
   if (n <= 1)
       1
       n * factorial(n - 1)

Here is sweet-expressions version 0.2 (draft), with infix default (it figures out when you have an infix operation from the spelling of the operation):

 defun factorial (n)
   if {n <= 1}
       1
       n * factorial(n - 1)

Here is sweet-expressions version 0.2 (draft), with infix non-default (you must surround every infix operator with {…}):

 defun factorial (n)
   if {n <= 1}
       1
       {n * factorial{n - 1}}

I’m still taking comments. If you’re interested, take a look at http://www.dwheeler.com/readable. And if you’re really interested, please join the readable-discuss mailing list.

path: /misc | Current Weblog | permanent link to this entry