readable adds additional abbreviations in the s-expression reader, for improved readability; it supports infix, optional standard function call notation, and optional indentation.

Note that well-formatted s-expressions continue to work as-is. The Common Lisp reader already supports abbreviations, such as 'x for (quote x); this library simply adds more abbreviations. As with the original s-expression notation, these abbreviations are generic (the notation does not depend on an underlying semantic) and homoiconic (the underlying data structure is clear from the syntax). Macros, quasiquoting, and other capabilities continue to work as-is.

You can select one of several tiers; each tier builds on the previous one:

  1. Curly-infix-expressions (c-expressions) start with traditional s-expressions and adds support for infix notation. In short, {a op b op ...} maps to (op a b ...). For example, {i < max} represents (< i max), and {a * {b + c}} represents (* a (+ b c)). These are "basic" c-expressions; "full" c-expressions support neoteric-expressions inside them.
  2. Neoteric-expressions (n-expressions) add support for traditional function notation. In short, f(...) maps to (f ...), and f{...} maps to (f {...}). For example, car(x) represents (car x), subseq("Hello" 1 3) represents (subseq "Hello" 1 3), terpri() represents (terpri), and fact{n - 1} represents (fact (- n 1)).
  3. Sweet-expressions (t-expressions) reduce the number of explicit parentheses needed (by deducing them from indentation). A line with only one n-expression, and no child lines, represents itself. Otherwise, the line represents a list; each n-expression on the line is an element of the list, and each of its child lines represents an element of the list (in order). Indentation processing is disabled inside parentheses, brackets, and braces, so it is backwards-compatible with typically-formatted files.

The following are examples of sweet-expressions and what they represent; if you enable the sweet-expression reader, the reader will accept either form:

Sweet-expression             Traditional s-expression
================             ========================
defun fibfast (n)            (defun fibfast (n)
  if {n < 2}                   (if (< n 2)
    n                              n
    fibup(n 2 1 0)                 (fibup n 2 1 0)))

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

Since you can choose a tier, you can choose to just support infix (and nothing else) if you want. This library is implemented by modifying the readtable. Note that this library implements Common Lisp versions of the Scheme specifications SRFI-105 and SRFI-110.

QuickLisp users can load readable using (ql:quickload "readable") - you can then enable the tier you'd like to use, e.g., (readable:enable-sweet). To stop you can use (readable:disable-readable). It is released under the mit-license.

This library only implements additions to standard s-expression notation; it does not create a whole new or different language. If you are trying to parse an arbitrary language of your own design, look instead for a parser generator, lexer, or general Text processor.

Homepage: Readable Lisp s-expressions

Tutorial (as document): Common Lisp tutorial for readable notations

Video: Readable Lisp S-expressions: Curly-infix-, Neoteric-, and Sweet-expressions (2013-09-09)


QuickLisp: (ql:quickload "readable")

Topics: language extension, s-exp syntax