Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's not a bad habit. It's just more practical.

Lisp lists are a data structure. One for example types code&data and computes with an interactive Read Eval Print Loop.

That's what one would write:

  CL-USER 35 > (+ (expt 23 2.4) (sin (* 44 0.23 22)))
  1854.5603
No one would type:

  CL-USER 36 > (+ (expt 23 2.4) (sin (* 44 0.23 22
                                     )
                                )
               )
Also when Lisp deals with s-expressions, the more compact notation is more useful: here Lisp does the layout itself:

  CL-USER 46 > (let ((*PRINT-RIGHT-MARGIN* 30))
                 (pprint '(+ (EXPT 23 2.4) (SIN (* 44 0.23 22)) (COS (+ 12 0.43 19.0)) (TAN (/ 1.4 0.77 3/4)))))

  (+ (EXPT 23 2.4)
     (SIN (* 44 0.23 22))
     (COS (+ 12 0.43 19.0))
     (TAN (/ 1.4 0.77 3/4)))
It's not

  (+ (EXPT 23 2.4
     )
     (SIN (* 44 0.23 22
          )
     )
     (COS (+ 12 0.43 19.0
          )
     )
     (TAN (/ 1.4 0.77 3/4
          )
     )
  )
Above is much harder to read and wastes a huge amount of space on the screen. Imagine that lists of are much longer and deeper nested. Finding the corresponding parentheses is usually done by using the editor (select a whole expression, have blinking or colored parentheses, etc.).

The main difference between Lisp and most other programming languages is that programs are written as a data structure: nested lists. Not only that: they are not static lists, but we can compute with them - that's the main appeal. It's a programming language, where it's easy and common to manipulate lists, even programs as lists. Thus the notation has not only be useful for reading code, but also for input/output by humans and programs. There a compact notation is much more useful, since tools will often create huge amounts of nested lists. For example imagine a macro for some Lisp functionality, like a complex loop expression. The macro expanded code can often be ten times larger as the input expression, yet we may want to see it in a debugger -> write that expression in a compact way.

I let Lisp indent my code and the system-wide standard indentation makes it easier to spot parentheses errors, since all code has the same shape rules.

  (progn
    (case foo
      (var (eval foo)))
    (fn (apply foo args)))
Since all code gets indented during typing, I can easily see that there is one parenthesis too much in the first case clause...

I wouldn't care to see the parentheses aligned and it makes the problem often more difficult to spot:

  (progn
    (case foo
      (var (eval foo
           )
      )
    )
    (fn (apply foo args
        )
    )
  )
I want the expressions to use less vertical space, so that I can see that the opening parentheses of the CASE clauses align. Anything else is just visual clutter.


The standard way is to close inline things inline and close multi-line things on a separate line.

Like this:

  (+ (EXPT 23 2.4)
     (SIN (* 44 0.23 22))
     (COS (+ 12 0.43 19.0))
     (TAN (/ 1.4 0.77 3/4))
  )
Instead of

  (+ (EXPT 23 2.4)
     (SIN (* 44 0.23 22))
     (COS (+ 12 0.43 19.0))
     (TAN (/ 1.4 0.77 3/4)))


It is very common for programmers who are new to Lisp to close their parentheses in the former style. However, it is a crutch that they soon do away with if they stick to the language for any length of time.


There are two reasons why sometimes the parentheses are on a separate line:

  ((paris (french))
   (los-angeles (english spanish))
   )
Something like above would be used if one often adds data clauses to that expression.

Also when there are comments on the last line, then sometimes the expression might be closed on the following like:

  ((paris (french))                 ; city 1
   (los-angeles (english spanish))  ; city 2
   )


Actually that's also wrong, I usually see this rule applied in other languages:

If the opening bracket is on the same line as content, then so is the closing bracket.

By this rule, we have two options:

  (+
     (EXPT 23 2.4)
     (SIN (\* 44 0.23 22))
     (COS (+ 12 0.43 19.0))
     (TAN (/ 1.4 0.77 3/4))
  )
or

  (+ (EXPT 23 2.4)
     (SIN (\* 44 0.23 22))
     (COS (+ 12 0.43 19.0))
     (TAN (/ 1.4 0.77 3/4)))

The first option has both opening and closing brackets on their own lines, while the second has neither. Note that I consider the function name to be part of the opening bracket since it's distinct from the parameters.

This is consistent with other languages:

  [1, 2, 3]
  f(x, y, z)
  [
    1,
    2,
    3,
  ]
  f(
    x,
    y,
    z
  )
instead of

  [1,
   2,
   3,
  ]
  f(x,
    y,
    z,
   )


Haskell is an odd exception with

    [ x
    , y
    , z
    ]
which looked really weird to me first but I’ve found it to improve legibility a lot. (Of course there’s a reason it’s idiomatic in Haskell and not elsewhere.)


Lisp has lots of multi-line expressions.

That the expression is ended I can see in the typical Lisp expression because of the block structure. The single parentheses does make the layout very cluttered and visually ugly. It gets even worse in typically larger Lisp code or data.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: