No operator precedence rules to remember.
Use math operators in higher order functions:
(reduce [1 2 3] +)
(compose + \*)
Simpler parser in the language.Use kebab-case variable names.
Use most symbols in variable names.
The last two are because of reduced ambiguity in the language. The benefits for readability can be huge. For example, I love question marks for predicates in Scheme.
(vector? x)
(filter [1 2 3 4 5] odd?)
I'm sure there are more benefits that I haven't thought of.To be fair, there just needs to be syntax for passing infix functions as a "normal" function, like parens in Haskell
(reduce [1 2 3] +)
foldl' (+) 0 [1, 2, 3]
And to allow `?` in names, it "just" shall not be used elsewhere.As an added bonus, you now know Lisp. This is how all Lisp syntax works: `(function arg1 arg2 ...)`. That's literally it.
The main one being if you want to add many many items together it's much easier IE (+ 1 2 3 4 5 6).
Instead of doing an operation between two numbers you are apply a function to a list of inputs. In the "+" function's case you are adding them together. With this in mind, it's no different than most other programming languages. You would never have your function be in the middle of your arguments/inputs.
In python its Foo(bar, bar) and not bar Foo() bar, which obviously doesn't make sense.
The real advantage of this notation is that it's much, much easier to stack calculations.
Example:
(/ (+ 34 68 12 9 20) 140)
You can imagine how the first part of that could come about:
(+ 34 68 12 9 20)
And then the second part (pseudocode):
(/ sum 140)
In Clojure it's easy to mash them together, or for example to paste the first calculation in the second.
(/ (+ 34 68 12 9 20) 140)
Want to go further? Easy: add another enclosing parens.
(* (/ (+ 34 68 12 9 20) 140) 1.5 2)
Note how we're stacking in a more human-readable order - a new calculation starts on the left hand side, the first thing we see as we read it.
Compare how verbose the alternative is:
((34 + 68 + 12 + 9 + 20) / 140) * 1.5 * 2
The problem with that is by the time I reach `20)` I have already forgotten what operation I'm in. I'd write it more like this:
(*
(/ (+ 34 68 12 9 20)
140)
1.5 2)
actually I'd write this as (/
(* 2 (/ 3 2) (+ 34 68 12 9 20))
140)
> ((34 + 68 + 12 + 9 + 20) / 140) * 1.5 * 2Why not (34 + 68 + 12 + 9 + 20) * 1.5 * 2 / 140?
If you work with clojure a lot, does it become natural?
99% of the syntax is just (foo arg1 arg2).
Where it really shines though is when you use the threading macro and inline comments to make really complex math a breeze to review:
(-> (+ 34 68 12 9 20) ;; sum all the numbers
(/ 140) ;; divide by a quotient for some reason
(* 2) ;; multiply by two for it's own reasonThe threads example in another comment is way better
(-> (+ 34 68 12 9 20) (/ 140))
mv foo.txt bar.txt # rename a file in the Unix shell
Except there are parentheses to delimit the command because commands can be nested in each other.(Some Lisps have interactive modes where you can drop the outermost parentheses, allowing you to type like this:
prompt> + 1 1
2
but usually the parentheses are part of the formal syntax; where this is just a hack in the interactive listener.)The design choice came about because the syntax started as an internal representation for a symbolic processing (formula manipulation) system that was being designed by John MacCarthy. The internal representation where the operator is first followed by its arguments was convenient because you don't have to parse around to identify them. You know immediately that by accessing the first position of the formula, there is going to be a symbol there which identifies its operator.
The internal form, and its written notation came to be used directly, while the symbol manipulation system came to be programmed in itself, so that its own "formulas" (source code) ended up in that form.
I know it's really hard to see how. (And honestly it's sometimes a little hard for me to see what the big deal is, but one of my first programming languages was a dialect of lisp so I can barely even remember not being comfortable with them.) But many people find that, once they get used to them, and especially if they learn to use an editor with a paredit mode, they can start to feel even easier to work with than infix syntax.
That allows for some nifty tricks like:
(reduce + [1 2 3]) ; returns 6
(In my functional programming languages, `reduce` also requires passing an initial value, like `foldl (+) 0 [1, 2, 3]`. But surely it should get a monoid instead of two separate arguments for the operation and the starting value!)
It's just a textbook monoid: an operation on two elements which produces another (+ or *), with a "neutral" element provided (0 or 1).
(some-function-name arg1 arg2)