Lost Ina Seaof Parentheses

Folk-etymology for the origin of the name "LISP" (see LispLanguage). In reality, a BackroNym.

...and here I thought it was LotsofInfernalStupidParentheses. My mistake; I must have just been in a worse mood. ;->

or "Lost In Stupid Parentheses" or "Lisp Is Simply Perfect" or "Lots of Irritating Superfluous Parentheses" or "Lots of Insidious Silly Parentheses". When thpoken with a lithp, the latht name becomth "Lotth of Inthidiouth Thilly Parenthetheeth". (No offense intended to people who normally speak with a lisp.)

Actually, it's Language Intended for Smart People ;)

[Language Intended for three-Star-Programmers?] No. If anything it is the antithesis of a language intended for three star programmers.


Probably somewhat off-topic for this page, but reading around wiki recently I've started thinking about a LispLikeLanguage? using ReversePolishNotation instead of all those parens. Crazy?

It exists and is called Forth. See ForthLanguage.


Here is some material from a UseNet article I wrote which describes the advantages of parenthesized prefix notation. Follow LispParenthesesUseNetArticle. -- KazKylheku

Note how many of the popular languages have syntax for statements and declarations which uses a prefix notation, like Lisp. Why is that? Because that syntax is easy to break into multiple lines and indent. The intent is that expressions should be kept small, so that they fit on one line when they are embedded into the "skeleton" syntax. Note how in the following, the for and if statements are prefix forms; they are introduced by a keyword.

  for (count = 0; foobar() < 42; count++) {
do_something();
if (xyzzy())
return -1;
do_something_else();
  }

This is easy to deal with as long as the expressions within the statement syntax don't get too long. Splitting infix syntax across multiple lines is an intractable problem of aesthetics.

In Lisp, everything is an expression, and all expressions use prefix syntax. There are various shorthand notations too, but they are all prefix based.

If we had an imaginary Lisp language that mirrored the C syntax, the above might look like:

  (for (setf count 0) (< (foobar) 42) (incf count)
(do-something)
(if (xyzzy)
(return -1))
(do-something-else))

What's the big deal? Now suppose that you want to split the for loop across multiple lines. Now the C syntax starts to become ugly:

for (count = 0;
foobar() < 42;
count++) {
do_something();
}

Eek! I cringe whenever I code something like this. In the Lisp-like syntax, there is no problem; there is a simple algorithm to get the formatting right: in a "statement-like" form, you line up the special parameters in a column, and then the remaining forms are indented one level:

  (for (setf count 0)
(< (foobar 42))
(incf count)
(do-something))

Most manual Lisp formatting boils down to a few simple choices. Given the list (X Y Z W ...), you can split it across lines like this:

  (X Y
Z W)

this would work if the list is a simple collection of data, with all the elements being parallel. Then there is this possibility:

  (X Y
Z
W)

This is good if X is a function or operator, and consequently the remaining three are its parameters. Then there are some variations:

  (X Y 
Z
W)

which might be used if X is a special operator in which Y plays some special role, and then the remaining are parallel elements, for instance:

  (if (< variable 42)
(zorch)
(splat))

or something like

  (X Y
Z
W)

when Y and Z are special parameters, and everything that follows is just forms to be evaluated, for instance:

  (destructuring-bind (a (b c))
(retrieve-list)
(do-something-with a b c)
(splat))

Once you learn these simple variations, the guesswork is over. You can format Lisp in a readable way that is readily understood by every other Lisp programmer, and are free to concentrate on its semantics.

I've been programming in Lisp for only two years, and I must say that writing and reading it is a pleasure. On the other hand, I've been programming in C for 14 years now, C++ for about half of that period, and I still struggle to make the code look good.

That's fair enough, but where in Lisp are the indentation and line-break rules defined? It seems they should be attached to the relevant defun, for code. (Sorry, I just need to read those books now...)

You format your code depends on the way function is defined. But can the PrettyPrinter do that for you in LISP?

Nothing could be easier.

 CL-USER> (defparameter *source* '(lambda (x) (let ((y (+ x 0.1))) (format t "foo! ~a~%" (+ x y)) x)))
 *SOURCE*
 CL-USER> (pprint *source*)

(LAMBDA (X) (LET ((Y (+ X 0.1))) (FORMAT T "foo! ~a~%" (+ X Y)) X)) ; No value
Slightly OT. but the built-in PrettyPrinter is one of the best little used CommonLisp features. For funky stuff to do with it, see for example http://www.merl.com/papers/TR93-17/. -- NikodemusSiivola


In fact, LISPs inventors had proposed a more human-friendly notation that somehow never made it into any production implementations (EmExpressions). Example:

 maplist[x;f] = [null[x] -> NIL;
 T -> cons[f[x]; maplist[cdr[x]; f]]]

The guarded expressions take the place of a (COND ....)

Speaking as an old PrologLanguage guy, this seems really natural to me. Add a unification algorithm and we're home ...


These types of notations did make their way into implementations---just not Lisp implementations! Look at languages like Haskell, ML and others.

There is nothing human-friendly about the notation; it's a cryptic obfuscation of the abstract syntax tree. Decoding the infix ambiguities requires work. What does null[x] -> NIL ; T -> cons[...] mean? Does the semicolon have lower precedence or higher than the ->? Maybe it means null[x] -> ( NIL ; T -> cons[...]) in other words, if x is null, compute some multiple values? From where were the missing parentheses removed?

If a machine needs a full blown LR(k) parser to disambiguate something, the human does also; the human brain may be amazing at pattern recognition, but it cannot take computational shortcuts. On sufficiently short programs, it can do a kind of holistic approach. Given sufficient training; you can look a textbook snippet of code and see the syntax right away, the same way that a chess grandmaster can just glance at a board configuration and "see" only good moves. But for anything sufficiently long, your unravelling of the syntax has to follow a parsing algorithm.

No, please, let's keep Lisp free of semicolon and infix diseases!


LISP's unconventional syntax is both the biggest reason for its longevity, and its greatest hindrance for becoming main-stream. Because LISP has such a uniform syntax, it becomes very simple to extend the underlying semantics which things like macros. The idea that LISP would be great, were it not for the parentheses, is a very old one. The most recent attempt at this is Dylan [DylanLanguage], a language which has a C/Pascal-like syntax. ML [MlLanguage] can be considered as a statically typed Scheme [SchemeLanguage] with a more conventional notation. -- StephanHouben

This is just your hypothesis, not fact. Computing history is littered with languages that are not popular, and many of them have conventional syntax. None of these "Lisp in better syntax" languages are popular, probably even less popular than Common Lisp, so where does that leave your hypothesis?

In the defense of PurelyFunctional languages such as ML, they also have something Lisp doesn't: functional optimization. This makes it possible to precompute many things at compile-time, and do extensive inlining and dead-code removal. Of course, this is not mutually exclusive with using EssExpressions as Lisp does, and it's a shame there are no pure-functional Lisps...

There are CL implementations that do many compile-time optimizations based on type inference and code analysis. See CMUCL for example. It certainly can do inlining, dead-code removal, block compilation, tail-recursive optimization etc., but I am not sure how much of the analysis the compiler does based on functional optimizations per se.


Interlisp included the SuperParenthesis?. It uses ']' to balance all the left parens up to the outermost '(' or the first '['. For example (from "TheEvolutionOfLisp")

 DEFINEQ((FACTORIAL
(LAMBDA (N)
(COND [(ZEROP N) 1]
  (T (TIMES N (FACTORIAL (SUB1 N]

-- ScottDe

Wow. That would really confuse me.

No, it wouldn't. Compare with the version without SuperParenthesis?:

 (DEFINEQ((FACTORIAL
(LAMBDA (N)
(COND ((ZEROP N) 1))
  (T (TIMES N (FACTORIAL (SUB1 N)))))))))

To the contrary, they don't really change readability much one way or the other, they just help writing the code when you're at the end of the function and it's time to start closing up all the parens. "Let's see... one, two, three, four, five...where was I? One, two..."

The universal popularity of editors that have support for matching parens made SuperParenthesis? much less important, so they're rare now. SuperParens? do have their problems; sometimes they hide an outright mistake, so many people using a good editor tend to outright dislike them.

They're a neat hack, though, whether they are a good idea or not.


See EditingLispCode.


I've actually developed two tools to deal with the parentheses in Scheme:

They both have their problems, the way I wrote them. BuildSyntax requires you to write your programs in another notation and then compile that notation to Scheme. Grayspace has a cheesy lexical analyzer, and so gets confused by character constants, parentheses in strings, and the like, but I am finding I prefer it for actual use. I am careful to make sure that the confusing lexemes rarely occur, or that the parentheses cancel. -- EdwardKiser


Out of interest, what editor do you guys use? I find Lisp syntax can be a pain when refactoring. When editing the last statement in a function it is easy to add or delete too many parentheses or but them in the wrong place. However, in general editing I don't find it a problem. I use XEmacs or DrScheme and both have parenthesis matching. If I can't see where my parentheses match it's a CodeSmell that a function is too large. -- NoelWelsh

I use the VimTextEditor. When e.g. adding another expression to a function or other implicit (begin ...), I go to the first opening parenthesis of the last form, then I press % to go to the matching closing parenthesis, then I press a, which will put me in insert mode right after the last expression. When deleting the last expression, I also go to the opening parenthesis and then do d%. Vim syntax highlighting will make it clear when parentheses are missing. Formatting the source with = will also indicate the problem. -- StephanHouben

I use GNU emacs. I never have any parenthesis problems. I think the reason is that I do all my editing on s-expressions---never just on tokens. Extensive use of C-M-{u,n,f,b,k,t} means that you always yank and transpose delimited expressions. After than, M-q reindents the function, and your eye can immediately tell if anything moves "the wrong way". -- AlainPicard

Thanks Alain. I think that is the insight I've been missing. -- NoelWelsh

I use NotePad for most of my source editing, which explains why I write tools like Grayspace. -- EdwardKiser Interesting. Why don't you go whole hog and just write code on paper (preferably with a non-cartridge fountain pen, and blotting paper)?

[Don't be silly. A nice goose quill and goatskin parchment works better for coding; or so my scribe tells me, although papyrus is said to have nice qualities, too.]


Well, the parentheses are clearly a feature. No experienced Lisp Hacker would want to live without them. Why? Because it makes editing source code so much easier.

Okay I give a hint what you could do with it.

Look at the following little and uninteresting code snippet:(expt (sin (sqr x)) x) . The whole thing is a Lisp expression and it has some nested subexpressions. So what are the parentheses doing there? They are grouping the expression(s). But as such they are a visual handle for the expression both at the beginning and the end of the expressions. So when you go there with your cursor you can use them to place direct manipulating editing commands there - especially when you use a mouse.

That is used by the LispMachine and for example Macintosh Common Lisp for a nice editing feature called 'mouse copy'. Let's explain the Macintosh Common Lisp version (which is way simpler than the Lisp Machine's sophisticated mouse support). Lisp programmers often like telling (long) names. As a typing aid, most Lisp development environments have a sophisticated completion facility.

So, how would one use that? Usually I have lots of screen space with lots of context specific Lisp code visible. When I start to type a new function definition, I usually might type something like that (defun compute-complex-html-page (weblog articles combiner) ... Later I don't type those words anymore. I just set my cursor and command-click on the symbols and expressions to click my code together. Transposing, replacing, exchanging code then just works by clicking on the expressions - and where can you click on, when you want to click on an expression and issue a direct manipulation mouse command? On the parentheses. Voila.


I'll say it again: none of this helps the poor soul who has to read LISP code on paper.

Indentation helps. Reading obfuscated code (no matter what language) is not fun.

But some languages make it easy to obfuscate code. In fact, in some languages it's so easy to obfuscate code that it's hard to write non-obfuscated code.

LISP encourages deep nesting, which has a high obfuscation potential. Consider a procedural program with an a conditional inside another conditional inside a loop, itself inside a method definition which is inside an inner class. Already nested too deep for easy comprehension by mere mortals, but this is only four levels, and it is hard to imagine a non-trivial LISP function that would require any less. -- AnonymousDonor

Whatever do you mean? Lisp exposes some sorts of nesting that aren't so visible in other languages (at least until one reaches enlightenment and the parentheses become invisible), but what's confusing isn't the number of visible nesting levels but the complexity of what's actually going on. There's no more reason in Lisp than in any other language to write "a procedural program with a conditional inside another conditional inside a loop inside a method definition inside an inner class". Which, by the way, is at least seven levels (an inner class, by definition, must be inside something else), not four. -- If the mere depth of visibly nested structures makes for confusion, then I dread to think how incomprehensible HTML must be to you. HTML -> BODY -> TABLE -> TR -> TD -> EM -> text is already seven levels, and much deeper nesting is commonplace. -- GarethMcCaughan

Indeed Lisp does encourage deep nesting, because every construct is some kind of top-level expression that is refined into subexpressions. The nesting can get quite deep even in functions that are just a few pages long. But this actually reveals a huge advantage of the parenthesized prefix notation: a very long, deeply nested expression can be split into multiple lines and formatted so that its tree structure is obvious. This is not true of InfixNotations or other ad-hoc syntax.

HTML was not intended to be coded by hand nor read by eye, even though the poor state of most HTML editors make this necessary for serious Web design. I am slowly moving over to perl to generate my HTML for me. -DavidBrantley

I would say that functions in any language that "are just a few pages long" are difficult to understand. Any time you can't see all the code of a method on screen at once seems to imply you haven't abstracted the algorithm enough. Lisp, I feel, makes this kind of abstraction easier since it's a functional programming language. -- TaoWang

.. just a few pages long

'just'? just? Ye gods ...

Hmm. Somebody please explain to me why an expression like

  x = f(y) + ((z < 42) ? a : (b + 1));
is difficult to read? Or how about
  Eks = FunctionOne(FirstArgument, SecondArgument, CallToAnotherFunction(FirstInnerArgument,
SecondInnerArgument), CallToYetAnotherFunction(OnlyInnerArgument));
Or perhaps you think that the example from above (spaces added for positioning emphasis),
  for  ( count = 0;
 foobar() < 42;
 count++ ) {
do_something();
  }
is in bad taste? Why, then, can't one format it as
  for (count = 0;
 foobar() < 42;
 count++) {
 do_something();
  }
and simply live with it? All this talk about how the Lisp presentation of source is so superior simply eludes me. I don't see it. <sigh>

Well it was introduced as "... some material from [article] which describes the advantages of parenthesized prefix notation.". AutomaticCodeLayout? is easier, but we don't care because we didn't have to implement that. The other (dis)advantages stand, mostly independently.


Would it help if lisp treated pairs of (), {}, and [] the same?

  x = f(y) + [(z < 42) ? a : (b + 1)];

[destructuring-bind (a (b c)) (retrieve-list) (do-something-with a b c) (splat)]

PLT Scheme does that already. Let-lists and conds become more readable that way.

Uh, no, it does not become more readable.

Come on, that's being dishonest. Typography in mathematics exploits differently sized or differently styled parenthesis for that exact purpose, and to deny that it doesn't help reading formula is quite blunt

[My 2c (1.1p) - I don't mind different size parentheses in mathematics but I hate when different styles are used within an expression 'cosmetically'. I think part of the CriteriaForGoodMathOrCompactNotation should be that parentheses be standardized within math - Sets are accepted as "{}" but are vectors "()", "<>" or "[]"? That notation should then inform programming. I think Lisp and Scheme are better sticking with "()" but new languages especially in the QuestForThePerfectLanguage should follow math which in turn should have unambiguous syntax (and semantics).]

Won't happen. Real maths - the proper research stuff, not just arithmetic - requires that one invent notation on the fly. The notation is purely to put on paper what's in your head and there is large negative value in trying to impose standards on it. Real mathematics will never have "standard" notation for things like vectors because they mean so many different things and are used in so many different places. There are those who even content that "doing maths" is actually the same as "inventing a language to discuss and then solve this problem I have here".

[Nothing is wrong with inventing on the fly, I agree that is part of the "process of maths", letting it evolve and change over time but once things have "stabilized" in a particular area, why not settle on a common notation? Surely no one is changing the definition of what a vector is? There may be other list-like objects or new types of vectors, tensors, spinors etc that need new notations but for "settled" objects, I disagree]

A finite sequence of numbers has many, many different "meanings", sometimes even having several meanings within a single context. You cannot have enough notations for them all. You may think this would be a good thing for programming, and you might be right, but it won't happen in maths. Looking to math to help you derive your notations in programming is a dead end - it won't help, it won't happen.

Mathematicians don't stick to the computer characters either, so unless you won't to go the way of APL you're already in trouble. Much of the "standard" mathematical notation is already undisplayable on regular terminals. Aleph_nought is the first of many examples I could give. If you spot an , report it immediately. If you choose to program with such symbols then do so with my blessing.

[We agree to disagree - in programming you can have fine nuances and multiple contexts but "=" means one thing, "==" in another. Yes, there is no such thing as the PerfectLanguage it's just an ideal and what I'm envisioning for maths may never happen. But I think what obtains now is based on the past, now that the mechanics of languages themselves are better understood, and maths is a type of language, albeit highly complex, we should be more rigorous. Display is trivial that's why we have things like MathMl and PostScript. Mathematica also has to make decisions on how it represents things, but deals with many types of mathematical objects. I don't see why there should be a disconnect between the mental and the mechanical, even if we accept a bit of a lag so as not to "drag" the former.]

I haven't seen a textbook that didn't use square brackets for vectors, being that they're degenerate matrices. I'd say it's already largely standardized. As for = vs ==, they're only distinct because of languages that give assignment a side effect. Saying 'a = 5' and 'if (a = 5)' is perfectly sane. The first states that an equality relationship exists, the second states the equality relationship as a condition. BASIC actually got something right, who'da thunk it? (though I think the LET keyword should have remained mandatory)

I guess I just don't understand what you're saying. You seemed to say that mathematicians should standardise the notation they use, and then programmers should design languages so that their syntax follows that used by the mathematicians. I'm saying that this falls down in two places. The first is that mathematicians will never standardise their notation(s) because of both what it means to "do math" and the sheer number of concepts to cover. The second is that whatever mathematicians might standardise on won't easily be represented on computers unless you either go the APL route (special keyboard), use the equivalent of a chinese character set, or resort to PNGs throughout your code.

BorlandJbuilder, a JavaIde, allows you to keep your source files in UTF-8 encoding. So yes, you can use greek letters etc in source code. Very fun. I put in an RFE asking them to put a variable whose name is Math.<unicode lower-case PI> as an equivalent for Math.PI, but they just laughed.

Will the contributors of the last two paragraphs please read through them and try to convert them into grammatically correct English so that they can be understood? I've re-worked some of the last - does that help? It makes sense of your paragraph, although "either" should not introduce three alternatives. The sentence beginning with "But" in the earlier paragraph remains to be straightened out.


(I am not the original contributor, and might the contributor not revisit this. I will try to explain one paragraph of the two, however, given that I am familiar with such aggregate expressions -- such that may be rather hastily written. The author, if he would see this, may pardon. The edited, annotated version follows. -- SeanChamp)

''BorlandJbuilder, a JavaIde, allows you to keep source files, such that the files would be made with a UTF-8 character encoding.

(Given) You can use Greek letters, etc, in (the UTF-8 encoded) source code.

I (the author) made an RFE (i.e., a request for enhancement), asking them (presumably, the developers of BorlandJBuilder) to put (i.e. to implement) a variable whose name is (or would be) 'Math'. (Given, or supposing:) 'unicode lower-case PI', as an equivalent for Math.PI -- but they just laughed.


Pardon my short introduction here: As someone who greatly appreciates the syntactic uniformity of LISP, and yet who realizes, "Not everyone 'digs', or otherwise expresses any appreciation about, LISP syntax", I may wonder, '"Why would anyone not have adopted the LISP language?"'.

While I am no striking celebrity, I thought that I might comment about this page -- in this page, and in some community -- upon such a perspective, my own. The comment, initial: This page, this one, it does serve as a good, rather effectual counter towards some of my own naivete about such a manner of question -- reexpressed thusly: "Why would anyone not like LISP?"

I have wondered in earnest as to why it may be that any person that programs a computer would not prefer LISP, when a LISP would be known as being viable. This page does serve -- in some -- towards the resolution of such a sense of mooted wonder.

To add to the page/topic-work, some -- not about the language, 'per se', but about people:

It may be that there have become some 'attitudes' expressed, and some 'attitudes, expressed aback, of people -- as across a general division, between two social groups, represented thusly: '"<A> uses a B/C/Java/other"', '"<B> uses a LISP"'.

So, though it might occur at any distance from any matter of syntax, per se, it might bear consideration as to whether the proverbial question would be, in any part, a question of 'attitudes' -- as to ask, "Why not LISP?" or, respectively, "Why?" Beside that, of course, languages other than LISP, (in whatever dialect of the said general language type) rather, non-LISP languages, have been more readily adopted, and more frequently applied, across all businesses, schools, and general computers.

Regardless, the standard LISP syntax -- such that employes a good many parenthesis -- is, in its manner, syntactically uniform. As such, it may be rather easy to "get started" about LISP, and to continue about it, without any concern about syntax.

Pardon my having stretched so-many words about the topic of this page, as it was already indicated. I consider that there is more discourse that is reasonable about the LISP languages than what has occurred, "afore this single, particular moment", and though not all of it would be so philosophical, yet may some be, as such.

[author: SeanChamp]

This is quite a convoluted prose to state some simple concepts... are you French? ;) I sure find it hard to follow the idea, even though the idea itself is simple. Might SeanChamp consider a simplification of his sintax (no pun intended)? A native Castillian speaker would apreciate it much!. fs


CategoryProgrammingLanguage


EditText of this page (last edited February 28, 2014) or FindPage with title or text search