Examples of Lisp formatting through history
kazimirmajorinc.blogspot.com
kazimirmajorinc.blogspot.com
(a (b (c (d (e
(f (g (h xxx yyy (i uuu (vv ww qq) (j
foo bar))))))))))
becomes allowed whereas (let ((a b)
(c d))
foo)
becomes not allowed -- you have to write it as (let
((a b)
(c d))
foo)
or (if you need the let clauses to line up) as (let
(
(a b)
(c d))
foo)
Well, the let form is such a unusual case that I will give a second example: (f (g xxx
yyy)
zzz)
becomes not allowed -- you have to write it as (f
(g xxx
yyy)
zzz)
or (if you need g's arguments to line up) as (f
(g
xxx
yyy)
zzz)
Although I used two spaces for every new level of indentation above, the choice of the number 2 is of course not an essential element of the style. foo x y = x >>= \a -> case a of
Leaf -> ..
Branch aleft aright -> ..
which translates into the Scheme pseudocode (define (foo x y) (bind x (lambda (a) (case a
((leaf) ..)
(branch aleft aright) ..)
Although such an indentation pattern (namely, multiple "unclosed" open parens on one line, which all get closed at once) is very uncommon in Scheme or Lisp code, I find it handy enough to trade off for certain other "competing" indentation patterns (namely, the one in the final example in grandparent) traditional in Scheme and Lisp.I have been meaning to put my .emacs.d (5800 lines) on Github. Do you want me to email you when I have done so?
By the way, any Emacker who shares my skepticism of the value of the traditional Emacs practice of having special indentation amounts for certain special forms and who prefers a slightly more regular/boring indentation style can get the TAB key to reflect that skepticism/preference with (setq lisp-indent-offset 2) and (setq lisp-body-indent 2) (or (setq lisp-indent-offset 4) and (setq lisp-body-indent 4) or such).
Disclaimer: untested on Emacs 23 or 24. (I'm still on Emacs 22.)
foo x y = x >>= \a -> case a of
Leaf -> ..
Branch aleft aright -> ..
Hanging lambdas yes, but I don't see the advantage of putting the
beginning of the case into the same line. foo x y = x >>= \a ->
case a of
Leaf -> ..
Branch aleft aright -> ..
But the example is a bit contrived, because you could write it this way: foo x y = do
a <- x
case a of
Leaf -> ..
Branch aleft aright -> ..(Not lining things up as in
(f xxx
yyy)
initially detracts from readability, but in my experience with the new style, readability goes back up to very close to where it was as I get used to the new style.) foo x y = x >>= \case
Leaf -> ..
Branch l r -> ..
modulo whatever syntax gets chosen. That would save an unnecessary temporary variable. (See https://groups.google.com/group/haskell-cafe/browse_thread/t...)Temporary variables clutter up the name space. While reading code you have to look for shadowing, or whether that variable is ever used again.
(let
((a b)
(c d))
foo)
Seems odd to me because the (a b) and (c d) are semantically the same but can't line up. Or, they can't line up without spending a new line on each function call, as if this were Java or something.Don't worry; I know Haskell isn't Java-like. (Haskell is Python plus Perl: Significant whitespace plus polymorphism based on external context of the expression. Written in the APL charset.)
You can do the same thing in Lisp and Scheme, where of course whitespace is not significant.
If you're asking if Haskell's significant whitespace somehow made it more probable that programmers would do it, the answer is, I do not know.
i recognize a lot of old school lispers follow a philosophy of "lisp empowers me so much that i don't need a team", so they do whatever they want and their productivity so godly that nobody says anything, but this isn't particularly helpful to increased lisp adoption, which benefits us all. maybe it isn't harmful either, but we who are already using it aren't in a position to judge this.
I use banner style in all languages and it works well.
If you write "(a (b (c (d (e (f" RET, TAB indents just as many spaces as it would if you had written just "(a" RET.
Lisp coders are accustomed to a certain pattern of indentation that would be analogous to the following in C, where xxx and yyy are typically many lines long:
while(aa){if(bb){
xxx}
yyy}
I am recommending for Lisp coders to avoid that pattern and to indent the above as follows: while(aa){
if(bb){
xxx}
yyy}
which is of course familiar to a C programmer and which we will refer to as "formula A". However, what will be unfamiliar to a C programmer is the motive behind my recommendation: namely, to make it possible to introduce into Lisp a new pattern of indentation, unfamiliar to C programmers and Lisp programmer (but familiar to Haskell programmers) in which you are allowed to write, while(aa){if(bb){
xxx}}
where again xxx is a place holder for many lines of code. However, it is important to note that the following would be a definite violation of the indentation style I recommend: while(aa){if(bb){
xxx}
yyy}
I recommend indenting that as formula A above. In other words, you can begin multiple multi-line s-expressions on the same line, but if you do, you have to close all of those multi-line s-expressions at the same time.>maybe you can post it anyways?
It's a little too long: about 90 lines of code. I could make it shorter by taking out the code that warns the user of the stylistic violation described above, but most user would want that code.
Anyways, this:
while(aa){if(bb){
xxx}
yyy}
is not banner-style indent, whereas this: while(aa){
if(bb){
xxx}
yyy}
is.It's a little too long: about 90 lines of code
Not too long for Bitbucket.
This "lisp style indenting" happens in Haskell every now and then too -- luckily all the big projects I looked at use fixed size indent. It's usually a sign of a programmer who hasn't written a lot of code, but I bet someone reading this will find some guy as good as Simon Marlow doing exactly that.
(let ((a b)
(c d))
foo)
I often write my lets and wheres in Haskell as let a = b
c = d
in foo
and have seen that style in other people's code, too.This is the ONE AND ONLY CORRECT INDENTATION STYLE for Lisp.
Because the defining feature of Lisp is allowing only one way to do things?
Clojure has been ahead of the curve on these commas, of course. Commas (and semicolons) are considered whitespace. They're available to pretty up your code's presentation however you like. It's like Clojure is committing in advance not to need many syntax characters.
http://en.wikibooks.org/wiki/Introduction_to_newLISP/Macros#...
It's interesting to see the old ones even if one is not a big lisp fan, though.