Live data from Hacker News

A difference between Haskell and Common Lisp

chrisdone.com

81–90 of 203 posts

Re: A difference between Haskell and Common Lisp

#81

Earlier quoted context omitted.

Minor nitpick. Technically, this: #(->> % (drop 3) (filter p) (take 5)) Is equivalent to: take 5 . filter p . drop 3

Is take 5 . filter p . drop 3 An anonymous function call in Haskell? I don't know the language (although it's on my to-learn sequence).

ghci will (usually) tell you:

    phil@arod:~$ ghci
    GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
    Loading package ghc-prim ... linking ... done.
    Loading package integer-gmp ... linking ... done.
    Loading package base ... linking ... done.
    Prelude> :t take 5 . filter (\ _ -> True) . drop 3
    take 5 . filter (\ _ -> True) . drop 3 :: [a] -> [a]
So it’s a function from List of a to List of a

Re: A difference between Haskell and Common Lisp

#82
post #72
post #67

Earlier quoted context omitted.

> > it was a standard developed by a committee > That's basically nonsense. > The core of Common Lisp was designed by mostly five people How is that different from what the OP said? It certainly seems fair to me to call a group of five people "a committee."

> fair to me to call a group a group of five people "a committee." Haha. So any team is a committee?

No. But the team that designed CL was.

Re: A difference between Haskell and Common Lisp

#83
Some of the Lisp and Haskell code examples aren't doing the same thing. For example, these two do completely different things:

    (remove-if-not #'p xs :count 5 :start 3)

    take 5 . filter p . drop 3
I don't like Haskell, and it's not immediately obvious to me how to achieve what the Common Lisp is doing, so I won't bother, but one way of writing the Haskell in CL would be:

    (loop for x in (subseq xs 3)
          when (p x) collect x into result
          until (= (length result) 5)
          finally (return result))
Another option would be to use subseq and remove-if-not, etc, but without lazy evaluation, the loop version will be more efficient. And though some Lisp people dislike LOOP, I like that it's easy to read, if not always easy to write ;-)

About the topic of the article, though, to me this seems like less a philosophical difference than a result of Haskell not having easy to use default and optional parameters. There's currying, but it's not a great substitute, and it's a little awkward to use.

I like the Common Lisp way, even if it's crufty at times, because the keyword arguments to functions like remove-if-not and sort are easier for me to use than chaining a half dozen functions. I don't have to think about whether I need to call filter before or after take or drop, etc. At the end of the day, it's a personal preference, though.

Another advantage is that I don't have to "roll my own" for common idioms.

Re: A difference between Haskell and Common Lisp

#85
post #79
post #59

Earlier quoted context omitted.

Well you can't have implicitly resolved typeclasses without a static type system. You could pass around explicit dictionaries with all your values or some such, but most of the value of explicitly sequencing relatively minor effects is only there if you have an extremely low-overhead way of doing so, and a system that can verify the correctness of that sequencing at compile time.

> You could pass around explicit dictionaries with all your values or some such, … if you have an extremely low-overhead way of doing so A lot of that plumbing could be hidden from the user given the right dynamic features. http://www.eighty-twenty.org/2015/01/25/monads-in-dynamicall...

This is a really, really interesting, well-written, accessible article even if you don't know the GHC or Racket internals. Thanks!

Re: A difference between Haskell and Common Lisp

#87
post #79
post #59

Earlier quoted context omitted.

Well you can't have implicitly resolved typeclasses without a static type system. You could pass around explicit dictionaries with all your values or some such, but most of the value of explicitly sequencing relatively minor effects is only there if you have an extremely low-overhead way of doing so, and a system that can verify the correctness of that sequencing at compile time.

> You could pass around explicit dictionaries with all your values or some such, … if you have an extremely low-overhead way of doing so A lot of that plumbing could be hidden from the user given the right dynamic features. http://www.eighty-twenty.org/2015/01/25/monads-in-dynamicall...

It sounds like racket generics are at least partway on the road to a type system. And those placeholder values seem a bit greenspunny - I'm not sure how they'd interact with native racket features (e.g. macros). (I mean, you are right, but in a degenerate sense you could implement typeclasses in any dynamic language by having your program construct strings and writing a Haskell compiler in that language that executed those strings at runtime. So the more relevant question is whether monad techniques can be used effectively in an idiomatic program).

Re: A difference between Haskell and Common Lisp

#88

I'm not entirely sure that this is due to philosophical differences. The fact that Haskell is lazily evaluated makes writing functions that do only one thing much easier, since there is no performance hit for writing code like: take 5 . filter (not . p) . drop 3 In a strictly evaluated language. This would involve iterating over the list three different times. (Kind of not really, since take 5 isn't going to be that…

Not really. It doesn't matter that Haskell is lazy by default, so long as you called the function on a lazy stream data structure. Clojure is strict but it can do this efficiently as well, I think.

Re: A difference between Haskell and Common Lisp

#89

The biggest difference between Haskell and Lisp is that Lisp is multi-paradigm, while Haskell is not. Haskell is more opinionated, and makes a bunch of decisions for you (that you can choose to work around/sugar/hack until Haskell looks like something else/does what you want). All the other things that Haskell comes with - strong typing, monads, lazy evaulation, can be written into common lisp, but whether you need t…

They can't be written in Lisp well, or at all. Strong typing with inference can't be bolted on. Monads that take advantage of this typing can't be bolted on. Changing Lisp to have lazy semantics across the board ain't gonna happen.

You might be able to write a Haskell interpreter from scratch that interacts with the Lisp environment, but you can't feasibly transform Lisp itself.

Re: A difference between Haskell and Common Lisp

#90
post #48
post #30

Actually Common Lisp supports a gazillion of different programming styles. The version with small functions, similar to the Haskell version: (subseq (remove-if (complement #'numberp) (butlast list 3)) 0 5) In above Common Lisp code, we use four different functions which do one task: * subseq sequence start &optional end => subsequence * remove-if test sequence => result-sequence * complement function => complement-fu…

> Check out the UNIX man for tail, grep, ... to see how strange above quote about 'unix philosophy' is. I wish someone would take that hoary old meme out behind the barn and put it out of our collective misery.

unix commands may not be the pinnacle of minimalism, but the most important thing UNIX taught is about composability. Yes, I did recognize the irony of the fact that the common lisp example was much more like a unix command line than the haskell example, but if you're talking about composing (relatively) small commands, unix is still a pretty good comparison.
Post reply on HN