Live data from Hacker News

A difference between Haskell and Common Lisp

chrisdone.com

71–80 of 203 posts

Re: A difference between Haskell and Common Lisp

#71

The difference is not one of "philosophy", but rather of using the right types . Haskell's so-called "list" type constructor is actually a type constructor of streams . Unsurprisingly, streams are much better than lists if you want to do stream processing.

>Haskell's so-called "list" type constructor is actually a type constructor of streams.

Most papers consider streams to be lists without a terminal constructor. Haskell lists are a superset of streams. All streams have infinite lengths, but only some lists have infinite length. (Again, this just comes down to definition, but this is how most functional papers describe it.)

Re: A difference between Haskell and Common Lisp

#72
post #67
post #52

Earlier quoted context omitted.

> standard developed by a committee You know that Haskell was developed by a committee and was designed to bundle the various research streams on lazy/statically typed/ purely functional programming languages? From the Haskell history: > ... to discuss an unfortunate situation in the functional programming community: there had come into being more than a dozen non-strict, purely functional programming languages, all…

> > 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?

Re: A difference between Haskell and Common Lisp

#74
post #52

Earlier quoted context omitted.

> standard developed by a committee You know that Haskell was developed by a committee and was designed to bundle the various research streams on lazy/statically typed/ purely functional programming languages? From the Haskell history: > ... to discuss an unfortunate situation in the functional programming community: there had come into being more than a dozen non-strict, purely functional programming languages, all…

As always, thank you for the clarification. My 6 month old is teething and waking me every 40 minutes starting around 3am. I'm mostly recalling from hazy, caffeine fueled memory. I like your posts -- so informative. I admit to knowing little about Haskell's history. I had assumed it was an outgrowth of ML -- itself having an interesting history intertwined with the LCF theorem-proving system. Thanks for the clarifica…

> My 6 month old is teething and waking me every 40 minutes starting around 3am.

Congratulations!

Re: A difference between Haskell and Common Lisp

#75
post #71

The difference is not one of "philosophy", but rather of using the right types . Haskell's so-called "list" type constructor is actually a type constructor of streams . Unsurprisingly, streams are much better than lists if you want to do stream processing.

>Haskell's so-called "list" type constructor is actually a type constructor of streams. Most papers consider streams to be lists without a terminal constructor. Haskell lists are a superset of streams. All streams have infinite lengths, but only some lists have infinite length. (Again, this just comes down to definition, but this is how most functional papers describe it.)

In chapter 4 of his book, Okasaki defines a type of both finite and infinite streams (which is really just the type of Haskell "lists"), and, in the remainder of the book, he only uses finite ones.

A stream of infinite length, which you call "stream" without qualification, is what I call "a function on the natural numbers". (Well, up to isomorphism.)

Re: A difference between Haskell and Common Lisp

#76
post #65
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.

> Well you can't have implicitly resolved typeclasses without a static type system. Yes, but that wasn't the feature mentioned in the GP comment. He mentioned lazy evaluation, with currying, static typing and monads as a consequence. But if monads are just a consequence of the type system, then I understand what he meant. > but most of the value of explicitly sequencing relatively minor effects is only there if you h…

> Well, extremely low-overhead of just about anything is certainly achievable with modern JITs[1].

Can't read twitter where I am, but to be clear I was primarily thinking of the code-readability overhead.

> Why is that necessary? You might as well presuppose the necessity of types :)

Well for me the value of using a monad to capture an effect is to be able to verify that I've sequenced that effect correctly at compile time. E.g. I use a monad to represent a database action that has to happen inside a transaction and the type system can enforce that I wrap it in a transaction. In a language without types it would be technically possible to do that, but entirely pointless, because if I get a mistake it's a runtime failure on that codepath either way. Maybe that was your point, but while monads are technically possible in dynamic languages, the technique that yields a lot of the value from using monads isn't.

> or, alternatively, say that you need a type system to verify that your monads are truly monads (i.e. obey the monad laws) at compile time, something Haskell doesn't do, either.

If I have a given defect rate in the sequencing of some effect, then isolating the fallible heart of that sequencing in a short piece of code is a big win (and I can e.g. flag that critical section for additional review). I do prefer to have a type system which verifies the monad laws at compile time, and I do think that the stronger the enforcement around the monad system, the more worthwhile it becomes to manage a given effect explicitly.

Re: A difference between Haskell and Common Lisp

#77

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).

Yes. It's three anonymous ("take 5", "filter p" and "drop 3") functions composed by the "." operator, creating another anonymous function.

One of the types, for example:

take :: Int -> [a] -> [a]

What means a function that takes an Int argument and returns another function, that takes a list and returns a list of the same type.

Re: A difference between Haskell and Common Lisp

#78
post #41
post #17

Or you could use Shen and spend less time philosophizing http://www.shenlanguage.org/

Could you elaborate? What about shen makes you say this?

I just wanted to point out that it's more comparison of imperative vs functional languages than Lisp and Haskell.

Shen is a Lisp with "Haskell philosophy".

Re: A difference between Haskell and Common Lisp

#79
post #59
post #51

Earlier quoted context omitted.

> higher structures like monads possible What is it about the features that you mentioned that makes monads possible? Lisp (or at lease Scheme and Clojure, which I'm familiar with) make monads trivially possible -- just as they are in Haskell. They're not as useful because those languages have other mechanisms that make monads largely unnecessary, but they're no less easy to express.

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...

Re: A difference between Haskell and Common Lisp

#80
post #71

The difference is not one of "philosophy", but rather of using the right types . Haskell's so-called "list" type constructor is actually a type constructor of streams . Unsurprisingly, streams are much better than lists if you want to do stream processing.

>Haskell's so-called "list" type constructor is actually a type constructor of streams. Most papers consider streams to be lists without a terminal constructor. Haskell lists are a superset of streams. All streams have infinite lengths, but only some lists have infinite length. (Again, this just comes down to definition, but this is how most functional papers describe it.)

That's one way of doing it, but most formally I think it has to do with whether you're considering the list type in a "data" sense or a "codata" sense. In either case you might be talking about the same "shape" of data, but streams are defined under observation as compared to construction.
Post reply on HN