Live data from Hacker News

A philosophical difference between Haskell and Lisp (2015)

chrisdone.com

41–50 of 181 posts

Re: A philosophical difference between Haskell and Lisp (2015)

#41
post #7

This is interesting to read having worked with Clojure, but never Haskell or CL. I expected the Haskell examples to look alien and the CL to look familiar, but the idiomatic Clojure solutions to the examples are almost identical to the Haskell solutions. E.g. take 5 . filter (not . p) . drop 3 becomes (->> s (drop 3) (filter (complement p)) (take 5)) ; for some sequence s I think it is also true of Clojure that it st…

Is there something similar to (->>) in Haskell? Edit: corrected “—>”.

Assuming that (-->) is either a typo of Clojure's ->> or ->, or some CL macro that operates the same (I don't know any CL, admittedly), in Haskell there is the somewhat common & (as in, available in the standard library and the widely-used lens library, but not part of the prelude and a lot of folks seem to eschew it in favor of composing in "the other direction" with . and $), which is defined as `flip ($)` (i.e. reverse function application) and visually ends up working the same as ->>:

    myList
    & map someFunction
    & filter somePredicate
    & sum
Other ML-ish languages typically provide this operator but under a different name, |> being a common one. One important note is that the mechanics here are a bit different than threading macros in lisp, since you're explicitly building the AST you want and using operator precedence (and implicit/automatic currying) to get the visual effect, rather than calling a rewrite rule. This means you can't have a straightforward reproduction of Clojure's -> macro, although in practice this never really matters, and when it does you can still fake it with flip (or, more readably, parens and a lambda).

Re: A philosophical difference between Haskell and Lisp (2015)

#42
post #7

This is interesting to read having worked with Clojure, but never Haskell or CL. I expected the Haskell examples to look alien and the CL to look familiar, but the idiomatic Clojure solutions to the examples are almost identical to the Haskell solutions. E.g. take 5 . filter (not . p) . drop 3 becomes (->> s (drop 3) (filter (complement p)) (take 5)) ; for some sequence s I think it is also true of Clojure that it st…

Is there something similar to (->>) in Haskell? Edit: corrected “—>”.

This comes for free from Haskell's automatic partial application (that arises from Haskell's pervasive use of function currying). So several different Haskell variants of Clojure's `compose` correspond to different versions of Clojure's threading macros.

Clojure's threading macros arise because it's a little bit more awkward in Clojure to partially apply functions (either anonymous functions with # or use `partial`) and it reads more fluently to just use threading macros there.

However, Clojure can do fancier things with variants of the common threading macros (https://github.com/rplevy/swiss-arrows)

Re: A philosophical difference between Haskell and Lisp (2015)

#43
post #7

This is interesting to read having worked with Clojure, but never Haskell or CL. I expected the Haskell examples to look alien and the CL to look familiar, but the idiomatic Clojure solutions to the examples are almost identical to the Haskell solutions. E.g. take 5 . filter (not . p) . drop 3 becomes (->> s (drop 3) (filter (complement p)) (take 5)) ; for some sequence s I think it is also true of Clojure that it st…

(filter (complement p)) is just (remove p), right?

Re: A philosophical difference between Haskell and Lisp (2015)

#44

There is a strange... kind of poetry with Haskell. It is like math on wheels, math applied to procedures, math with... time. Its appeal to me is like the appeal of math to me, not like real analysis math but abstract algebra math. The beauty, the purity of mathematics of younger days that once became lost after encountering the sad complexities of the world. Understanding every little aspect and being able to prove e…

I followed a (pure) mathematics education, and I totally dig lisp. On the other hand, I abhor haskell and hate almost everything about it!

This comment would be more informative if you briefly explained why you abhor it and hate almost everything about it.

Re: A philosophical difference between Haskell and Lisp (2015)

#45

There is a strange... kind of poetry with Haskell. It is like math on wheels, math applied to procedures, math with... time. Its appeal to me is like the appeal of math to me, not like real analysis math but abstract algebra math. The beauty, the purity of mathematics of younger days that once became lost after encountering the sad complexities of the world. Understanding every little aspect and being able to prove e…

I'd hazard to say that the abstract algebra is more foundational, more of a bedrock on which the sophisticated cathedrals like complex analysis can be built.

Re: A philosophical difference between Haskell and Lisp (2015)

#46
I really enjoy programming (a lot!) in both Common Lisp and Haskell, and I agree with his comments on both languages.

Chris and I probably differ in that I love the kitchen sink built in functions. Also, it is also common to write lots of very short Common Lisp functions.

Re: A philosophical difference between Haskell and Lisp (2015)

#47

I dislike the lisp convention of remove-if, remove-if-not, etc. Filter and take isn't much better. The python convention is much nicer: [x for x in foo if x not in y] Turns out, this can be expressed in Lisp: (list x for x in foo if x not in y) I've implemented this into my fork of Lumen that runs on Python. https://github.com/shawwn/pymen It feels very nice to use: > (list x for x in (range 10) if (= (% x 2) 0)) """…

For those that didn't know, Haskell does of course have list comprehensions: [x| x Here's an example finding consonants: [c| x

Haskell's list comprehensions actually started off as more general monad comprehensions, were later restricted to lists, and are back behind a GHC language pragma.

Re: A philosophical difference between Haskell and Lisp (2015)

#48
A small note: composition is not better than monolithism. The article makes it feel like it is but it is not. They are two perfectly valid approaches when it comes to solving problems. Often a mix of both is used.

Monoliths tend to be better at solving common real life problems efficiently while composition is better suited for unexpected abstract problems. We need both.

For example GNU binutils are not very "unixy", with plenty of "monolithic" options but they still work well with pipelines.

Re: A philosophical difference between Haskell and Lisp (2015)

#49

There is a strange... kind of poetry with Haskell. It is like math on wheels, math applied to procedures, math with... time. Its appeal to me is like the appeal of math to me, not like real analysis math but abstract algebra math. The beauty, the purity of mathematics of younger days that once became lost after encountering the sad complexities of the world. Understanding every little aspect and being able to prove e…

"Dream-like" is a good adjective for Haskell programming. Sometimes when writing Haskell I just zone out and let my subconscious do whatever it wants, and the type system provides enough structure that this usually gets you working code. It's a very fun creative exercise.

Re: A philosophical difference between Haskell and Lisp (2015)

#50

Earlier quoted context omitted.

Is there something similar to (->>) in Haskell? Edit: corrected “—>”.

This comes for free from Haskell's automatic partial application (that arises from Haskell's pervasive use of function currying). So several different Haskell variants of Clojure's `compose` correspond to different versions of Clojure's threading macros. Clojure's threading macros arise because it's a little bit more awkward in Clojure to partially apply functions (either anonymous functions with # or use `partial`)…

What's the syntax in Haskell for thread-first (-> in Clojure) which inserts the result of the previous operation as the first argument, versus thread-last (->>) which inserts it at the end, so is more amenable to composed curried functions?
Post reply on HN