3 ms·
Most Lisps aren't so great with arithmetic. Afterall arithmetic notation has been refined through 100's of years to be readable and concise, and I've never seen
by zosima 14y ago
Most Lisps aren't so great with arithmetic. Afterall arithmetic notation has been refined through 100's of years to be readable and concise, and I've never seen anybody use prefix notation for operators voluntarily. But infix notation can be added easily: this is a quick'n dirty solution in Clojure with left associativity, no precedence and many gotchas. Incanter has a much better implementation called $= with less gotchas and many more features:
(defmacro arith [& args]
(letfn [(res [v]
(cond
(vector? v) (apply arith-body v)
(list? v) (map res v)
:else v))
(arith-body [s & args]
(reduce (fn ([expr] expr) ([expr [op arg]] `(~op ~expr ~(res arg))))
(res s)
(partition 2 args)))]
(apply arith-body args)))
(defn deriv [f]
(let [dx 0.001]
(fn [x] (arith
(f [x + dx]) - (f x) / dx))))
((deriv (fn [x] (arith x * x))) 3)
Another common problem is the piping of results from one function to the next:
(f
(g
(h a)))
where you usually want to start reading the code in the lower rightmost corner and go upwards towards the left. Very messy in many lisps.
Clojure has solved that problem with the threading macros, yielding postfix notation when you need it the most:
(-> a h g f)
Piping subresults between functions really doesn't get much better in any language.
And that's of course some of the appeal of Lisp: The syntax may start controversial, but you can choose most of it yourself and make it depend on the problem, your tastes and of course, your readers.
- lispm 14y agoWell, Lisp has excellent arithmetic capabilities. Bignums, Floats, Ratios, Complex numbers built in. Infix notation is provided by macros or read macros. Infix notation is provided by math packages on top of Lisp: Macsyma, Reduce, Derive, Axiom, ... Those provide REAL extensive math syntax capabilities, not just what typical programming languages provide.
- zosima 14y agoSloppy me. I would of course be referring to arithmetic syntax or notation. And you make my point exactly: there is many ways to express arithmetically heavy operations in a natural, readable way.
- draegtun 14y ago>Piping subresults between functions really doesn't get much better in any language Piping operations like this can also be found in OCaml, F# and Perl6. For eg. in Perl6 this is called a Feed Operator (http://perlcabal.org/syn/S03.html#Feed_operators http://perlcabal.org/syn/S03.html#Feed_operators) and your example would look like this: a ==> h ==> g ==> f;
- zosima 14y agoYes, many languages support something eqivalent. Classically object oriented languages not the least: a.h().g().f() I feel that prefix notation is one of the greatest impediment to the uptake of Lisps. And I think it's important to underscore that you can (idiomatically) choose prefix, postfix or infix depending on the character of your problem. If the code is (unnecessarily) hard to read, then express it differently. The language encourages it.
- mryall 14y agoActually the equivalent of the above Perl 6 code would be: f(g(h(a))) It can get kind of gnarly when any of the values are non-trivial.
- zosima 14y agoTranslated directly, yes. But when you have objects and no piping operator, library designers will often choose to implement pipe flow as method chaining. See e.g. jQuery, Scala's collections or many ORMs, like SQLAlchemy.