| Lisp has a lot syntax. It is just a bit different and it looks different externally. Lisp has a 2-stage syntax. The first stage is the syntax of s-expressions, which is surprisingly complex. S-Expressions provide a textual syntax for data: symbols, lists, pairs, strings, various number formats, arrays, characters, pathnames, ... The first stage is implemented by the 'reader' and can be reprogrammed by an ancient API to the reader via read tables. The second stage is the syntax of the Lisp programming language. This is defined on top of s-expressions and is really a syntax over data structures (not text). This Lisp syntax deals with: data items, function calls, special forms (thirty something) and macro forms. This syntax stage is implemented as part of the interpreter/compiler (EVAL, COMPILE, COMPILE-FILE) and can be extended by writing macros, symbol macros and compiler macros.
In earlier dialects it could also be extended by writing so-called FEXPRs, functions which get called with unevaluated source code (-> data in Lisp). So, we get a lot of complex syntax due to special forms and macros. It just looks a bit different, since the data syntax is always underneath it (unless one uses a different reader). For example a function definition would be: (defun foo (a b) (+ (sin a) (sin b)))
The syntax for that is: defun function-name lambda-list [[declaration* | documentation]] form*
With more complex syntax for 'function-name', 'lambda-list' and 'declaration'.Lambda-list has this syntax: lambda-list::= (var*
[&optional {var | (var [init-form [supplied-p-parameter]])}*]
[&rest var]
[&key {var | ({var | (keyword-name var)}
[init-form [supplied-p-parameter]])}*
[&allow-other-keys]]
[&aux {var | (var [init-form])}*])
Not every valid Lisp program has an external representation as an s-expression - because it can be constructed internally and can contain objects which can't be read back.Not every s-expression is a valid Lisp program. Actually most s-expressions are not valid Lisp programs. For example (defun foo bar)
is not a valid Lisp program. It violates the syntax above. |
Readtables aren't any more ancient than the rest of ANSI INCITS 226-1994 (R2004) (the language standard formerly known as X3.226-1994 (R1999)), but the interface to them is very low-level and non-modular.
The current readtable is specified by a dynamic variable, so the readtable facility can be made modular with a nicer interface, in a portable manner. This is exactly what the library Named-Readtables does: http://common-lisp.net/project/named-readtables/
Now realize the significance of this: Common Lisp is the only language allowing total unrestricted syntactic extension and <i>modification</i> in a modular and (somewhat) composable way.
I've been using named-readtables for the past month, and between it and Quicklisp, I haven't been this excited about programming in CL since I started (which is 8 years ago, not that long, but I'm not a total noob either).