I crave both the power of code-as-data and nice syntax, which is why I love Lisp.
I crave both the power of code-as-data and nice syntax, which is why I love Lisp.
I could attempt to prove to you that "conventional syntax" is inherently superior to Lisp syntax, but that would be a waste of both of our time.
Yes, trying to prove falsehoods is a waste of time.
Conventional syntax is neither conventional nor suited to humans. (If it's "conventional", why isn't there more agreement as to what it is? If it's suited to humans, why aren't there more than 100 who actually know it for any given language?)
add 1 and 2 and 3
The syntax is a bit terse but if you teach people a good way to read it it becomes much more readable than 1+2+3
The only reason we prefer that way is that we are thought that syntax when we do math in school, I have found it much easier to teach people lisp who have no or very little formal education in math.
(/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a))
Yeah, so it divides (the addition of (-b and the (sqrt of (the difference between (the product of b and b) and (the product of 4, a and c))) by (the multiplication of 2 and a))Right, that's much easier than
(-b + sqrt(b*b - 4*a*c)) / (2*a)
(-b plus the sqrt of ((b times b) - (4 times a times c))) divided by (2 times a)I see you omitted some parenthesis in the "conventional" expression, relying on the fact that multiplication takes priority over substraction. Making this fact explicit is exactly what makes Lisp better, especially for more complex domains: delegating priorities to the notation, freeing brain capacity for the actual problem.
(defun foo (a b c)
#I(
(-b + sqrt(b*b - 4*a*c)) / (2*a)
))
CL-USER 8 > (foo 1 2 3)
#C(-1.0 1.4142135)It may be bikeshedding, but I would not let 'blue is better than red, because the sky is blue' pass either.
(/ (+ (- b)
(sqrt (- (* b b)
(* 4 a c))))
(* 2 a))
It tells me:* there's a quotient of 2 things
* the first thing is a sum of -b and a sqrt
* the second thing is a product
and so on. Pretty nice. Of course, mathematical notation is more terse.
You sound as if you think that putting salt on grapefruit is inherently strange, while in actuality there's a very good reason to do so: it reduces the perception of bitterness.
I'm not saying that it's impossible to like Lisp's syntax, but empirically most people prefer the ALGOL-like syntax
Empirically, most people prefer what they are already familiar with, so I'm not sure what this is supposed to prove, other than most people are already more familiar with Algol-like syntax.
For me, Lisp syntax has the definitive advantage that the first identifier in every expression tells me what to expect. I.e., I don't have to scan to the right to figure out what kind of expression this is. For me, this makes code much more readable. And this makes Lisp syntax more "nice".
Closer to "the human"? Do you know more than 3 people who know C++ operator precedence?
Humans don't handle operator precedence very well.
You don't have to know an entire operator precedence table to read and write idiomatic infix-notation code. Precedence is defined such that common expressions evaluate as people intuitively expect (a notable counterexample is "x & y == z" in C). Parentheses are always available to clarify more complicated expressions.
Come to think of it, humans usually add and subtract by stacking numbers vertically. I don't think you can point at infix notation as "the" human-friendly notation.
This feels like a discussion based in fiction...
(/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)) ?
I take it you think there is something intrinsically wrong with that idea?
I find it very hard, without bracket counting, to see exactly what the '+' and '/' bind to. With the more traditional:
(-b + sqrt(bb-4ac)) / (2a)
I find in only a glance I can tell what everything is binding to.
It must be nice to live in a world with only 4 infix operators and expressions that have only 3 infix operators.
For example, lots of folks think that sqrt should be a prefix operator, not yet another function. I suppose you're going to assume that the top bar will serve as parentheses.
BTW "-b + sqrt(bb-4ac) / 2a" is the interesting expression. Is it "(-b + sqrt(bb-4ac)) / (2a)" or "-b + (sqrt(bb-4ac)) / 2a)" And, are you certain what "bb-4ac" means? (There's at least one major language where it doesn't mean "(bb)-(4ac)".)
And that's how the exceptions swallow the rule. And, it's also how we get infix programming languages where that's definitely not true, and so on. Where should we make the switch?
Also, only four? What about set operations?
(/ (- (sqrt (discriminant a b c)) b)
(* 2 a))Other notations are used, but with a frequency similar to pre-fix (lisp) and post-fix (forth). "Associativity" (not affected by order of evaluation) only makes sense for in-fix.
But it really could just be familiarity, I guess. I can't see how to determine it either way. But regardless of the cause, there's overwhelming evidence that people, in fact, prefer in-fix.
How many people have seen anything other than in-fix? Of those, how many got a fair shot at an alternative?
If it's "idiomatic", why is there such disagreement?
> Why then has math (which is read and written only by humans)
Convention has a lot of value. That said, mathematicians don't have to worry about getting things wrong. It's just paper, and they're happy to let humans fix up the errors.
> Parentheses are always available to clarify more complicated expressions.
Unnecessary parentheses are how humans deal with the fact that they can't handle infix.
here's IPL, an influence of lisp, also a list processing language (c/p from wikipedia)
IPL-V List Structure Example
Name SYMB LINK
L1 9-1 100
100 S4 101
101 S5 0
9-1 0 200
200 A1 201
201 V1 202
202 A2 203
203 V2 0
How human LISP feels now ;) ?I find Lisp (particularly Clojure) much more aesthetically pleasant, in that it communicates better with me. With Paredit, it's even better to the touch.
(If there one day came to exist something even better on these metrics, then I'm sure I would start to prefer it aesthetically.)
Doubly agreed! I learned Clojure just over a year ago and will never look back. My attitude to people complaining about parents is that that should just get over it. That one hang up is actually holding them back.
(defun substitute-in-replacement ($-value replacement) (cond ((null $-value) replacement) ((null replacement) ()) ((eq (car replacement) '$) (cons $-value (cdr replacement))) (T (cons (car replacement)) (substitute-in-replacement $-value (cdr replacement)))))
From: http://www.csc.villanova.edu/~dmatusze/resources/lisp/lisp-e... with one paren moved.
I remember, when I was taking a class on AI, looking for some sort of style guideline that would help me get through the learning curve, but the FAQ (I want to say it was comp.lang.lisp) just had "coming soon." So this would be the allegro editor in 2001 or 2002. It may be obvious to an experienced hand, and perhaps if there was some sort of best practices when I was learning it I wouldn't have had the same problem, but I just remember the frustration of my mind playing tricks on me and (even with syntax highlighting) trying to match parens that I thought were there.
I haven't read a lisp style guide, Emacs just takes care of indentation - it is immediately clear when a paren is wrong because the shape of the function is wrong. If you are writing lisp with an editor that doesn't do this, get a better editor, don't blame the language.
Arguably Python -- but to get that, Python sacrificed the possibility of both usable anonymous functions and the possibility to cut-paste a code fragment and just ask the editor to reindent.
Hardly worth the price.
It's quite possible my experience as a programmer today would be different than when I started -- I mean, I made it through a few chapters of SICP without such troubles, but in the back of my head was the memory of trying to figure out my logic error in a bit of code when it was really a misplaced paren.
Actually, it's pretty obvious even without doing all that. CONS always takes two arguments.
(defun substitute-in-replacement ($-value replacement)
(cond ((null $-value) replacement)
((null replacement) ())
((eq (car replacement) '$)
(cons $-value (cdr replacement)))
(T (cons (car replacement))
(substitute-in-replacement $-value (cdr replacement)))))
CL-USER 5 > (compile 'substitute-in-replacement)
;;;*** Warning in SUBSTITUTE-IN-REPLACEMENT: CONS is called with the wrong
;;; number of arguments: Got 1 wanted 2
SUBSTITUTE-IN-REPLACEMENT
Lisp compilers able to present these error messages are in use since more than 40 years. Common Lisp has them since day one. (defn thingies [id]
(->> id
fetch
read-json
:rows
(map :thingy)))
(Of course, my code is often more complex and messier than that, even when using ->>, but some fairly significant percentage of my code does look that simple.)I'm sure there's stuff to criticize about Clojure, but we can look at real-world code in another mainstream language (Javascript+node.js? PHP? Java?) and point out readability problems too. (Python maybe being an exception in terms of readability-in-the-small, for things that fit in the mainstream style. Though as someone pointed out, there's maybe some problems with manipulability.)