Hacker News new | ask | show | jobs
by troad 639 days ago
I don't think (fn x y z) is all that different to fn(x, y, z). The lack of finicky operator order or other syntax footguns is nice. You're basically looking at the AST as you work. You're one fewer layer of abstraction removed from the logic you are composing.

In real world Lisp, alignment conventions are used that make even a fairly nested function readable at a glance. You'd also generally work using something like paredit, so you're kind of shuffling the S-expressions around like legos. It's not a language that you'd want to write in something like Notepad.

The most important thing about the syntax, though, is that since it's basically the AST, a Lisp macro can effectively manipulate the AST directly and on the fly. This is incredibly powerful, and would be hard to achieve in an Algolian language like Python.

1 comments

Because we're so used to thinking parenthesis provides an order of evaluation precedence, the fact that 'fn' is within the parenthesis is very confusing. even (fn(x y z)) would have been better. having the function name and it's arguments just next to each other with no syntactic separation is hard to follow. it's like doing arithmetic this way: "add x y z" , is it x+y = z or x=y+z? I'm sure I can get over this hurdle though.

Thanks for suggesting paredit.

I hear you. Try to shift your thinking from statements to expressions, it will make things easier.

The placement of parentheses is not arbitrary. The parentheses enclose expressions, and the nesting of expressions builds a tree. This tree, in effect, is your program's AST. Your C program compiles to something very similar; Lisp just makes it explicit.

"Add x y z" is exactly what it sounds like, if I said those words to you. The add function is usually +, so (+ x y z) is an expression that adds x, y and z, and the whole expression evaluates to the result. You can nest expressions however you like, so, for example, (+ x (* a b)) adds x to the result of the expression (* a b), which evaluates to the result of multiplying a by b.

Values and expressions are effectively interchangeable. Any one of +, x, or y, could be replaced by an arbitrarily complex expression (yes, the function too - you could replace it with a call to a higher order function, which would return a function that is then called over x and y).

The neat thing is, that's basically[0] all the syntax Lisp has. There are no reserved keywords. Everything works as per above, and can be redefined at will. You can change the language's if and else to work any way you want. You can redefine Lisp's reader to change the syntax of the language to absolutely anything you can imagine, and doing so is quite easy, since you're effectively already working at the AST level.

And you can do all of this in a running REPL without even needing to restart it.

If you're interested, check out Common Lisp: A Gentle Introduction to Symbolic Computation by David S. Touretzky.

[0] Macros are the other piece of the puzzle, but to understand them you would need to read up on Lisp more. Once you understand Lisp macros, the advantages of Lisp's syntax become obvious.

Wow, thanks very much for the detailed reply. I'm a bit excited and interested to read up on it more. I can only imagine, it must have inspired so many enthusiast level and esoteric languages.