Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

LISP Sans Parenthesis, 1958 to 2013, a Survey

264 views
Skip to first unread message

Xah Lee

unread,
Jun 25, 2013, 5:46:35 AM6/25/13
to
this might be interesting.

〈LISP Sans Parenthesis, 1958 to 2013, a Survey〉
http://xahlee.info/comp/lisp_sans_sexp.html

plain text version below.

────────── ────────── ────────── ────────── ──────────

In the lisp community, especially Common Lisp, many seasoned lispers hold the idea that, those who dislike lisp's nested parenthesis syntax are outsiders, who don't get lisp. This is factually incorrect.

This page lists lisp projects that implements alternative syntax to solve the controversial nested parenthesis (S-Expression; SEXP) problem. I probably missed some. Please comment if you find any missing.

────────── ──────────
M-Expression, John McCarthy LISP (1958)

In computer programming, M-expressions (or meta-expressions) were intended to be the expressions used to write functions in the Lisp programming language. Data to be manipulated using M-expressions was to be written using S-expressions. M-expressions were used for the original theoretical language in early papers about Lisp, but the first working implementation of Lisp interpreted encodings of M-expressions as S-expressions, and M-expressions were never actually implemented.

from Wikipedia M-expression

The project of defining M-expressions precisely and compiling them or at least translating them into S-expressions was neither finalized nor explicitly abandoned. It just receded into the indefinite future, and a new generation of programmers appeared who preferred internal notation to any FORTRAN-like or ALGOL-like notation that could be devised.

〔History of Lisp 1979-02-12 By John McCarthy. @ www-formal.stanford.edu…〕

────────── ──────────
CGOL (1973)

• 1973 CGOL

CGOL[1][2] (pronounced “see goll”) is an alternative syntax for the MACLISP programming language, featuring an extensible algebraic notation. It was created by Vaughan Ronald Pratt.

Vaughan Ronald Pratt is known for his work in MACLISP, the Knuth–Morris–Pratt algorithm, and his work together with Knuth, and James H. Morris

────────── ──────────
Dylan (1992)

• ≈1995 Dylan (programming language). A Common Lisp based language created by mostly Apple, aimed as the industrial LISP.

Initially, Dylan used a Scheme-like prefix syntax, which is based on s-expressions…

By the time the language design was completed, it was changed to an Algol-like syntax, designed by Michael Kahl, with the expectation that it would be more familiar to a wider audience of programmers

────────── ──────────
Scheme srfi-49 (2003)

• 2003 〈Scheme srfi-49 Indentation-sensitive syntax〉 http://srfi.schemers.org/srfi-49/srfi-49.html

This SRFI desccibes a new syntax for Scheme, called I-expressions, with equal descriptive power as S-expressions. The syntax uses indentation to group expressions, and has no special cases for semantic constructs of the language. It can be used both for program and data input.

It also allows mixing S-expressions and I-expressions freely, giving the programmer the ability to layout the code as to maximize readability.

────────── ──────────
Clojure Lisp (2007)

Clojure

Here's a sample Clojure code, from Wikipedia:

(let [i (atom 0)]
(defn generate-unique-id
"Returns a distinct numeric ID for each call."
[]
(swap! i inc)))

Here's some syntax example from Clojure's manual.

list (a b c)
vector [1 2 3]
maps {:a 1 :b 2}
sets #{:a 1 :b 2}
deftype #my.klass_or_type_or_record[:a :b :c]
defrecord #my.record{:a 1, :b 2}
metadata map. ^{:a 1 :b 2} [1 2 3]
regex (#"pattern")
anonymous function literal. #(...) ⇒ (fn [args] (...))

────────── ──────────
Arc Lisp (2009)

• Arc Lisp, a new lisp created by the famous Paul Graham. Arc (programming language).

I've used Lisp my whole programming life and I still don't find prefix math expressions natural. —Paul Graham

We also plan to let programmers omit parentheses where no ambiguity would result, and show structure by indentation instead of parentheses. I find that I spontaneously do both these things when writing Lisp by hand on whiteboards or the backs of envelopes. —Paul Graham http://www.paulgraham.com/arcll1.html

In Arc, you can write

(if a b c d e)

to mean:

(if a
b
(if c
d
e))

source: http://ycombinator.com/arc/tut.txt
Racket Lisp (2011)

────────── ──────────
• ≈2012 Racket Scheme Lisp. () [] {} can all be used interchangeably.

Racket was PLT Scheme Lisp. It was lead by Matthias Felleisen. Matthias is well known in lisp programing community at least as lisp book author. He co-wrote:

How to Design Programs (2001) amazon
A Little Java, A Few Patterns (1998) amazon
The Little MLer (1998) amazon
The Little Schemer (1996) amazon
The Seasoned Schemer (1996) amazon

PLT Scheme Lisp is renamed Racket in 2010. I'm not sure when is the various brackets equivalence introduced.

Here's a excerpt from Racket's manual at http://docs.racket-lang.org/reference/reader.html#%28part._parse-pair%29.

When the reader encounters a (, [, or {, it starts parsing a pair or list; see Pairs and Lists for information on pairs and lists.

To parse the pair or list, the reader recursively reads data until a matching ), ], or } (respectively) is found, and it specially handles a delimited .. Pairs (), [], and {} are treated the same way, so the remainder of this section simply uses “parentheses” to mean any of these pair.



For syntactical advantage of multiple types of nesting bracket, see:

Nested Syntax Design: XML vs LISP
Hacker Fads & Fashions: Is XML Syntax the Stupid Brother of Lisp? Hey, Check Out Their Young Sister HTML5!

────────── ──────────
Readable Lisp S-expressions Project (2012)

〔Readable Lisp S-expressions Project 2012-08-09 By David A Wheeler. @ readable.sourceforge.net…〕

This is a syntax transformation tool, for Common Lisp and Scheme Lisp and other Lisps.

On its home page, it has a very well presented video, explaining the whys and hows.

It also has a comprehensive survey of the alternative lisp syntax issue. See: 〔Readable s-expressions and sweet-expressions: Getting the infix fix and fewer parentheses in Lisp-like languages 2006-06-17 By David A Wheeler. @ www.dwheeler.com…〕

────────── ──────────
Other, Smaller Players or Defunct Projects
wisp (2013)

〔wisp: Whitespace to Lisp: An indentation to brackets preprocessor to get more readable Lisp 2013-03-26 By Arne Babenhauserheide. @ draketo.de…〕
Common Lisp cl-2dsyntax

• 〈Common Lisp cl-2dsyntax〉 (an indentation-sensitive reader system) http://lisp.hyperprostor.unas.cz/cl-2dsyntax/

The cl-2dsyntax is an indentation-sensitive reader system. Published in the public domain. Because lispers read the code by indentation and not by parentheses, I've decided to write a reader macro for this.

It's up to you when to use this, I'm going to use it in a dumb editor such the Notepad (when I can't choose better).

am not sure who wrote it, when, or whether this is robust library or a proof-of-concept code.
lisp-smile ;LISPIN (2005)

• Genyris Scripting Language http://sourceforge.net/projects/genyris/

• 〈LISPIN〉≈2005. Dead. http://wayback.archive.org/web/20080517144846id_/http://www.lispin.org/

• lisp-smile (defunct) https://code.google.com/p/lisp-smile/

Norbert_Paul

unread,
Jun 25, 2013, 6:58:06 AM6/25/13
to
Xah Lee wrote:
> this might be interesting.
No

Richard Fateman

unread,
Jun 25, 2013, 5:03:36 PM6/25/13
to
There's a version of CGOL for common lisp, I believe.
I haven't tried it in many years, but here's a link.

http://www.cs.berkeley.edu/~fateman/cgol/cgol.1/tap-parser.cl
http://www.cs.berkeley.edu/~fateman/cgol/cgol.1/tap-cgol.cl

or see the directory.

The reality, as I see it, is that parentheses are just fine in
the sense that people who initially object to them eventually
learn to appreciate them, especially with a good (indenting)
editor or pretty-printer.

The idea that infix arithmetic is easier to read is an
over-simplification, and perhaps just false.


Just recently I had occasion to look at this paper:
High precision evaluation of nonlinear functions
by Siegfried M. Rump


which contains the following infix expression...

(a2 * b2 - (((x - a1 * b1) - a2 * b1) - a1 * b2))

To implement it I rendered it in lisp, where it looks like this

(- (* a2 b2) (- (- (- x (* a1 b1)) (* a2 b1)) (* a1 b2)))

or indented, like this

(- (* a2 b2)
(- (- (- x
(* a1 b1))
(* a2 b1))
(* a1 b2)))

spending a minute or two to adapt to the conventions here makes
the latter version, in my opinion, more readable.

der_gavio_fhurer

unread,
Jun 25, 2013, 7:00:05 PM6/25/13
to
do you like shamales?

Xah Lee

unread,
Jun 25, 2013, 11:01:02 PM6/25/13
to
hi Richard,

great to see you post. Hope all's well.

I think that CGOL in Common lisp is a great Resource. Thanks.

Xah

Jecel

unread,
Jun 26, 2013, 5:55:40 PM6/26/13
to
Xah

> Please comment if you find any missing.

I don't seen the ones I have used in this list:

- RLISP, part of the Reduce package (late 1960s)
http://en.wikipedia.org/wiki/Reduce_%28computer_algebra_system%29

- MuSIMP, an extension of MuLisp and part of the MuMath package (late 1970s)
http://en.wikipedia.org/wiki/MuMATH

I would also include Logo as an example of a Lisp with a different syntax. To me, the only real difference between Logo and a "real" Lisp is that its EVAL (called RUN) doesn't take an environment as an argument.

- Jecel

Xah Lee

unread,
Jul 1, 2013, 4:06:45 AM7/1/13
to
Thanks Jecel. I added your info.

some of the ones you mention i am not sure qualify, as the are specialized apps. Logo is also on the border, because it's a complete new lang and never had nested bracket syntax to begin with, in that regard, Mathematica is also one.

jurgen_defurne

unread,
Jul 1, 2013, 3:01:44 PM7/1/13
to
Op dinsdag 25 juni 2013 23:03:36 UTC+2 schreef Richard Fateman het volgende:
I just came to read another thread from 1997, and there also the statement about infix versus postfix was made.

However, in a typical program there is not very much computation. I have written and maintained several applications in what people today commonly call "business intelligence", and my experience is that most code is function calls, followed by assignments, and then a whiff of computations.

Currently, I am in a C# environment, which of course means C derived syntax.

Function calls are expressed as function(arg, arg, ...). In Lisp they are expressed as (function arg arg ...). Except for the place of the first parentheses, this is exactly the same.

Assignments are infix, which is place = expression. In CL they are (setf place expression). I have it difficult to believe that the infix version would deliver more productivity.

Then computation itself is indeed infix. If one needs to do difficult computations, then a library will probably be used, which leads to the first point, function calls. For simple computations, infix might pose a little problem, but if you haven't evaluated it first on paper, then you are already heading in the wrong direction (COBOL's computational statements were also not exactly enlightening).

The only thing that I have personally a gripe with is CL structures. I do find the way of working with C structs easier to read.

E.g.
struct_type struct;

struct.field = value;

versus

(let
((struct make-struct_type))
(setf (struct-field struct) value))

I find that the 'struct-selector' form for Common Lisp becomes a little faster more unwieldy than the C way.

Something else about programmer productivity: I always take more time to design than to program, so it is only good knowledge of a language that makes me more productive in that part. When using advanced features of a library, I spend more time testing to understand it. Once understood, the programming also only takes little time.

I personally think that the best productivity comes from libraries matched to the problem at hand, when what you model in your mind can be easily expressed using them.

Regards,

Jurgen

Jecel

unread,
Jul 1, 2013, 3:07:21 PM7/1/13
to
Xah Lee wrote:

> some of the ones you mention i am not sure qualify, as the are specialized
> apps.

Not quite - they were general purpose languages that were distributed as part of specialized apps. Just like AutoLisp, for example.

> Logo is also on the border, because it's a complete new lang and never had
> nested bracket syntax to begin with, in that regard, Mathematica is also one.

It depends on the Logo implementation, but many allowed you to be as Lispy as you liked. Some, for example, had prefix versions of all their infix functions. So you could get the same result with these two expressions:

:base + :offset

add :base :offset

And most versions of Logo allow you to have a variable number of arguments if you use parenthesis. So if you use "sentence" (APPEND, in Lisp) without parenthesis it must have exactly two arguments, but you can write>

(sentence [1 2 3] :odd [10 11 12] [cat dog mouse])

to join the four lists into a single one. You can also do:

(plus 1 2 3 4 5 6 7 8)

which is not possible with the infix syntax, though it is exactly the same primitive function.

While some Lisps have a fancy IF THEN ELSE syntax, others have a Scheme-like IF instead. So how close to Lisp Logo is depends on the Logo and also on the programming style.

About Mathematica, I thought about including it as an example but am not familiar enough with to be sure it would as a Lisp rather than as a Lisp inspired language.

-- Jecel

Pascal J. Bourguignon

unread,
Jul 1, 2013, 4:06:47 PM7/1/13
to
jurgen_defurne <jurgen....@pandora.be> writes:

> Function calls are expressed as function(arg, arg, ...). In Lisp they
> are expressed as (function arg arg ...). Except for the place of the
> first parentheses, this is exactly the same.

Well, there are those useless commas, and worse, those useless
semicolons…


> The only thing that I have personally a gripe with is CL structures. I
> do find the way of working with C structs easier to read.
>
> E.g.
> struct_type struct;
>
> struct.field = value;
>
> versus
>
> (let
> ((struct make-struct_type))
> (setf (struct-field struct) value))
>
> I find that the 'struct-selector' form for Common Lisp becomes a
> little faster more unwieldy than the C way.

See: http://groups.google.com/group/comp.lang.lisp/msg/190d771c0e033a1c

(-> car engine power) vs. car.engine.power
or more probably, vs. car->engine->power

(setf (-> struct field) value) ; should be nice enough.


> Something else about programmer productivity: I always take more time
> to design than to program, so it is only good knowledge of a language
> that makes me more productive in that part.

Yes, this is important. And one thing that lisp has for it here, is
that since it stresses much less the syntax than other programming
languages, when you think about the design of a system in the context of
lisp, you're more free. Just write stuff in parentheses, and you
already have a design that's processable, perhaps even runnable, just
implementing a few macros or functions, see for example:
http://groups.google.com/group/comp.lang.lisp/msg/a827235ce7466a92


> When using advanced features of a library, I spend more time testing
> to understand it. Once understood, the programming also only takes
> little time.
>
> I personally think that the best productivity comes from libraries
> matched to the problem at hand, when what you model in your mind can
> be easily expressed using them.

That, and a REPL, as long as trying random expressions doesn't crash
your environment.


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You know you've been lisping too long when you see a recent picture of George
Lucas and think "Wait, I thought John McCarthy was dead!" -- Dalek_Baldwin

Rupert Swarbrick

unread,
Jul 1, 2013, 4:22:14 PM7/1/13
to
jurgen_defurne <jurgen....@pandora.be> writes:
> The only thing that I have personally a gripe with is CL structures. I
> do find the way of working with C structs easier to read.
>
> E.g.
> struct_type struct;
>
> struct.field = value;
>
> versus
>
> (let
> ((struct make-struct_type))
> (setf (struct-field struct) value))
>
> I find that the 'struct-selector' form for Common Lisp becomes a
> little faster more unwieldy than the C way.

Well, I guess that the "right way to do it" is something like

(make-struct_type :field value)

This has the advantage of being shorter to write and also of avoiding
the possibility of using the structure before all its fields have been
initialised.

If you are writing a class in C++ then you can solve the problem of
uninitialised fields by only declaring constructors that are given
enough information in their arguments to correctly set up all the member
variables. C structs (in C!) don't allow you to do that, but C does
provide a syntax that lets the user initialise everything as the memory
is allocated:

struct_type struct = { foo, bar, baz }; /* (if I've remembered it right) */

I think that this is analogous to the line of lisp I wrote above (except
that the programmer has to remember the order of the struct members,
since we haven't got an equivalent of keyword arguments).

Of course, when you write your (defstruct struct_type ...) form, you can
pass nil as the constructor-name argument and you won't get a
make-struct_type function defined. Then you can define make-struct_type
however you choose, maybe making some arguments required.[1] Or do even
cleverer sanity-checking on the arguments... ("No, I don't believe that
this foreign array is an exabyte long...")


Rupert


[1] Maybe a defstruct ninja can instead do this with defstruct's
constructor-arglist argument. I've never worked out how, but
possibly this is just me being dense...

Rupert Swarbrick

unread,
Jul 1, 2013, 4:23:26 PM7/1/13
to
"Pascal J. Bourguignon" <p...@informatimago.com> writes:
> That, and a REPL, as long as trying random expressions doesn't crash
> your environment.

gforth, I'm looking at you... :-)

Rupert
0 new messages