This is a non-problem if you're using Lisp. (+ x y z) accepts an arbitary number of arguments and the operator precedence problem does not exist since there is no operator precedence.
This is a non-problem if you're using Lisp. (+ x y z) accepts an arbitary number of arguments and the operator precedence problem does not exist since there is no operator precedence.
Mathematical notation is not an archaic practice that is followed out of a respect for tradition, or a doctrine that has been developed from first principles, it is something that has evolved (and continues to do so) because it has been useful.
Now in mathematics, there is no equivalent of a 200,000 line piece of software. The number of identifiers a mathematician works with in any given work is small, even if the work is large (many pages of derivation).
Mathematics notation is ambiguous and inconsistent. One letter names are preferred so that xy can denote the product of x * y. So much so that mathematicians reach for other scripts like Greek rather than make a multi-letter name. Then, inconsistently, we have things like sin(x).
Consider that xy(z + w) is likely interpreted as the product of x, y and z + w. It has the same syntax as ln(z + w), the natural logarithm of z + w, not the product of l and n.
Professionally printed mathematics resorts to the use of special fonts to visually resolve these things. This problem is so serious that everyone who is anyone in mathematics goes to the trouble of professional typesetting, even in minor papers.
In software, the program-defined functions form vast vocabularies. They cannot all be assigned to infix operators without creating mayhem. Many functions have 3 arguments. Seven argument functions are not uncommon. Those also cannot be infix.
In spite of what the author may say, real Python code is chock full of "import foo" and "foo.bar.baz(this.or.that(), other.thing())".
Calling people’s use of LaTeX to type their homework “professional typesetting” seems like a stretch. Professional typesetting would be something like: send your hand-written manuscript to a full-time typesetter, and wait for them to do the work.
A better description would be “goes to the trouble of using math typesetting software designed by experts”. But is this really so strange? People use even more sophisticated software than that for making image collages of cats with mustaches, for modeling platonic solids, for adding their favorite song to a frivolous home movie, ....
Probably not "one plus two" -- I think + is essentially a variant of & which is a ligature for "et", and I guess most languages put "and" between the things being combined. But I'd be surprised if (x/y)^2 was said "x over y all squared" by many people before this notation. But the notation is clearly more designed for thinking on paper than for explaining down a phone line.
When I am doing algebra on my computer, I hope I have a tool like Graphing Calculator (not "Grapher"!) that lets me simply drag a term from here to there, and automatically figures out what needs to happen to keep the equation balanced.
2. They have, except they use Σ for the prefix version. When it's more than a couple terms, and there's a pattern to it, Σ (prefix notation) is far more convenient than + (infix notation).
If programming languages look like they do because they're taking the useful notations from mathematics, why doesn't your favorite programming language have a Σ function? Who's being stubborn here?
But they're optimized for different things. Using the same tool for infinite length sequences and fixed length sequences doesn't make a whole lot of sense. We often have different types for them (tuple/record vs. list/array) too.
What exactly "doesn't make a whole lot of sense" about (+ a b)? (It doesn't look the same as you wrote it in school? Neither does "3+4j", or "math.sqrt".)
Being able to use the same tool for different types of data is precisely what makes high-level programming so powerful. As Alan Perlis said, "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures." Having only one way to add numbers (in languages that do that) is a great feature.
Python's insistence on these pre-selected groupings of functionality has always made it frustrating for me to work with. The two ways to add numbers look and work nothing alike. Does "TOOWTDI" not apply to math?
(Yes, I'm also frustrated and confused that Python has built-in complex numbers, and a standard 'math' module with trigonometric functions, but math.cos(3+4j) is a TypeError. What possible benefit is there of having a full set of complex-compatible functionality, but hiding it in a different math module, with all the same method names?)
`reduce(op.add, [x, y])` works. Python could remove it's infix ops and use only prefix ones. But prefix ones aren't obvious. And as Guido says, readability matters.
Further there is no reason to suppose that any group of humans act optimally in this area when they clearly act on the whole so illogically and sub optimally in every other area of human endeavor.
It asks respondents to prove the much more complex question of why different groups may prefer a particular notation instead of taking the much more simple and direct route of explaining why the poster prefers a particular notation.
In short its not a missile its chaff.
Mathematics uses prefix, infix, suffix, circumfix, and some more complex notations; basically any pattern any computer language uses probably is inspired from math even if math doesn't use the notation for the same operation or operator symbol.
(eql (* x (+ y z)) (+ (* x y) (* x z)))
I wonder if its famed sense of enlightenment is partly just overcoming the mental hurdle of it's syntax.Edit: typo fix, had x/z mixed up
(= (* x (+ y z))
(+ (* x z) (* y z)))
Or: (= (* x (+ y z))
(+ (* x z)
(* y z)))
Or: (= (* x
(+ y z))
(+ (* x z)
(* y z)))
Or: (= (+ (* x z)
(* y z))
(* x (+ y z)))
Or: (= (+ (* x z)
(* y z))
(* (+ y z) x))
Or: (= (+ (* x z)
(* y z))
(* (+ y z)
x))
I think the last one makes the relationships quite clear.Writing legible equations is an art form, as is writing sexps.
Edit: If you think lisp is ugly, compare with regexps. For bonus points, explore writing regexps with lisp, e.g. with Emacs's `rx` macro. I think you won't find a more easily maintainable way to write them.
(x * (y + z)) eql ((x * z) + (y * z))
Or: (y + z * x) eql (x * z + (y * z))
With different precedence: x * (y + z) eql x * z + y * z
But now you have to remember precedences and mentally regroup the expression.xz + yz = x(y + z)
when using operators?
That seems wrong.
(= (* x (+ y z))
(+ (* x z) (* y z)))
As x*(y + z) = x*z + y*z
e.g. (+ y z) means you add y and z with highest priority.Large teams don't want artists, they want replaceable parts.
This is true for a lot of "frameworks" and especially true for modern fontend web frameworks (which have a compile/build step).
x * (y + z) = x * z + y * z
x * (y + z) =
x * z + y * z
x * (y + z)
= x * z + y * z
x *
(y +
z)
=
x *
z
+
y *
z
etc.If it's about formatting, given that this is what this thread is about, you can use code formatter for lisp languages exactly like for any other language, in fact they are even easier to write for lisp because of the consistency of S expressions.
If you are talking about macro, then you're in the same boat as other languages that have macros, C, Rust, ect... And remember that the first rule of macros is to not use macros, except for when you absolutely have to, and in those cases it is the most elegant solution. If you have devs inventing DSLs for everything, then lisp isn't your problem.
Thankfully, Michelangelo and Leonardo were not in large teams.
Which do you aspire to be: a cog or an artist?
(eqn x * (y + z) = x * z + y * z)
where you write and test an `eqn` macro that rewrites everything in the correct syntax. x * (y + z) = x * z + y * z reduces to
($= x * (y + z) = x * z + y * z)
Specifically its more complex only in that the entire expression is wrapped in ($= )In order to give x y and z values to run it simply wrap it in a let and give them values.
(let [x 1 y 2 z 1]
($= x * (y + z) = x * z + y * z))
alternatively wrap it in a function (defn testme [x y z]
($= x * (y + z) = x * z + y * z))But this observation does not change my point: that the parent comment is saying "Lisp already has the ability to do + on lists", but the reason "+ on lists" makes sense is because Lisp is using the underlying associativity of mathematical +. And the latter associativity property, for abstract mathematical "+", is what the blog post is describing/exploring.
In addition/relation to floating-point, another way in which addition is not associative in computing is if there are type conversions. (+ 1 1 0.1) is not the same as (+ 1 (+ 1 0.1)). The former will do an integer addition to produce 2, and then that is coerced to 2.0 which is added to 0.1. The latter adds 1.0 to 0.1, and then adds that to 1.0: two floating-point additions.
In languages that don't have bignums (which could include some Lisp dialects) whether overflows occur can depend on the order of operations, even when all operands are integers.
The reason we can have a n-ary + is that three or more arguments can be decimated through a binary +. The concept of + is defined as a binary operation.
Lisps have variadic functions that are blatantly non-associative, like, oh, list. (list 1 2 3) isn't (list 2 3 1).
((->> z)
y
x)
In clojure there is an interesting package https://github.com/rplevy/swiss-arrows which allows one to perform successive operations with explicit placement of the result of prior evaluation by placing a <> in the form ((->> (z <>))
(y <> 7)
(x <>))
In practice it seems like there is often less need to do so as many similar functions or the same variety have the same ordering and other options like as-> exist too.There is also the idea of processing math expressions infix as expected when desired.
https://github.com/rm-hull/infix
($= 3 + 5 * 8)
; => 43I've written tons of code in both language families. In infix/prefix (i.e., Algol-family) languages, I frequently wish for a nice consistent prefix syntax. In prefix-only (i.e., Lisp-family) languages, I can't say I've ever wished for infix notation.
I don't understand what the perceived issue is with infix notation, except for unfamiliarity -- and that passes soon enough.
What are the guarantees on add(a,b,c) versus a+b+c?
If do add(1.0e30, 1.0, -1.0e30) is that the same (aka IEEE fp addition is noncommutative)
You might be thinking of associativity. Both addition and multiplication are commutative up to NaN.