Live data from Hacker News

A difference between Haskell and Common Lisp

chrisdone.com

121–130 of 203 posts

Re: A difference between Haskell and Common Lisp

#121
post #52

Common Lisp has these kitchen-sink functions and macros because it was a standard developed by a committee whose goal was to incorporate several popular implementations of Lisp that each had several decades worth of of cruft. Lisp was big enough business at the time that having several mutually incompatible versions of Lisp was making knowledge sharing and business difficult. And having a standard was important for m…

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

Hmm. I looked at the list of five and thought to myself: "four legends and... who on earth is Scott Fahlman?" Turns out he invented the smiley! TIL

Re: A difference between Haskell and Common Lisp

#122

The main difference is: it is trivial to build an efficient Haskell implementation on top of Common Lisp, keeping interoperability with the rest of the system. And it is impossible to do it the other way around, to build a Lisp on top of Haskell.

https://wiki.haskell.org/Haskell_Lisp

Re: A difference between Haskell and Common Lisp

#123
post #117
post #70

Earlier quoted context omitted.

If you're interested in exploring the relationship of Lisp and the lambda calculus you might find this interesting: http://www.flownet.com/ron/lc.html https://www.youtube.com/watch?v=8qC1iZN5ozw

Nice article, but the language embedded here is exactly the untyped lambda calculus, not a Lisp. You can tell because there are no tags: pair is given as \x y sel -> sel x y, which is indeed the textbook way to encode pairs but does not provide enough to write CONSP. If you wished to implement a subset of Lisp in LC faithfully you would need an encoding for sums - which would not be all that hard, but does reflect th…

> does not provide enough to write CONSP

Yes, that's a very good point. That's why I said, "If you want to explore the relationship between Lisp and ULC..." and deliberately not, "If you want to see how to embed Lisp in ULC..."

Writing CONSP actually makes a very interesting exercise.

Re: A difference between Haskell and Common Lisp

#124
post #73

Earlier quoted context omitted.

Well, Common Lisp is Lisp. Scheme, Clojure etc. are lisps, with lower-case "l" ;)

That's just wrong. Clisp is the most popular lisp bearing the name, but the LISP, Lisp, or lisp family includes Scheme, and Clojure. if you just refer to Lisp, you may be referring to Clisp, the lisp family, or maybe even LISP 1.5, the lisp equivalent of V7 unix.

Clisp is an implementation of Common Lisp. Common Lisp includes a core of the original Lisp. Lisp programs from the 60s can either be run or ported to Common Lisp with little or no effort.

Clojure is FULLY incompatible with any other Lisp dialect or Lisp derived language. Porting code means 'rewrite'.

Re: A difference between Haskell and Common Lisp

#125
post #14

Haskell has strong typing and lazy evaluation, which makes it easy for functions to take only one argument at a time. Although a function could take a tuple parameter, it's usually rewritten to take each component of the tuple as a separate parameter, which makes the strong typing and built-in currying simple, higher structures like monads possible, and a syntax to suit this style. Lisp functions and macros OTOH must…

You can have currying in a dynamically-typed, strictly evaluated language.

Re: A difference between Haskell and Common Lisp

#126
Real general question about function composition - when you're comfortable with it, how do you think it to yourself, or say it to yourself, like what's your shorthand mental model?

I was able to really intuitively get comfortable with unix piping a long time ago, so instead of:

take 5 . filter p . drop 3

I'd be thinking, ok, take a thing, drop the first three, grep (or whatever), now take the first five. It felt intuitive because each step solved a problem, and then I'd move forward into the future, and have to only think of one additional solution (head -5) assuming I did the previous steps right.

Meanwhile, take 5 . filter p . drop 3 is in the opposite order, from right to left.

Maybe I'm just saying that left association is easier to think about than right association. Don't you feel that weird recursive bump in your head, the increasing mental stack, when you are dealing with function composition and right association?

Re: A difference between Haskell and Common Lisp

#127
post #68

Earlier quoted context omitted.

> The "UNIX philosophy" is good, it's just that UNIX doesn't really follow it. It never did, beyond some examples in beginner books. > Look at `cat` for example. It might as well be `str + str...`. Or look at `grep`, it's basically `filter` or `reduce` at heart. Then look at the options of `cat`. On my Linux system cat has a -n option, which numbers the output lines. If it were following the 'UNIX philosophy', this o…

"On my Linux system cat has a -n option, which numbers the output lines. If it were following the 'UNIX philosophy', this option would not exist." Gnu's not Unix. "The GNU coreutils version of this on my Linux box behaves this way" is not a good way of getting at finer points of what is or is not Unix-y. That said, -n exists in BSD cat as well. It's not required by POSIX, though.

My thoughts exactly. There are implementations of cat which don't have '-n' option:

    http://git.suckless.org/sbase/tree/cat.c
    http://plan9.bell-labs.com/sources/plan9/sys/src/cmd/cat.c
Not only "Gnu's not Unix", it's also not that much interested in following "Unix philosophy". Which isn't that bad, from a user perspective: users want more capable tools, even if it impedes composability a bit.

Re: A difference between Haskell and Common Lisp

#128
post #76
post #65

Earlier quoted context omitted.

> 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 compil…

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

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

That's an advantage of having a type system, not of having monads. There are other ways to type-check effects without monads (at least not explicit monads, and the monad laws don't need to be checked): http://blog.paralleluniverse.co/2015/08/07/scoped-continuati...

Re: A difference between Haskell and Common Lisp

#129

Real general question about function composition - when you're comfortable with it, how do you think it to yourself, or say it to yourself, like what's your shorthand mental model? I was able to really intuitively get comfortable with unix piping a long time ago, so instead of: take 5 . filter p . drop 3 I'd be thinking, ok, take a thing, drop the first three, grep (or whatever), now take the first five. It felt intu…

I like imagining functions as various pipes, the real world ones. Compose is that short pipe that connects two others. I imagine that the data comes from the right and needs to be output on the left of the function. I then can read such line (take 5 . filter p . drop 3) twice. Once following the order of creation (ie. we're laying our pipes first) and then the second time in reverse, following the data and function applications. That did the trick for me when I first learned about function composition coupled with (auto)currying.

Re: A difference between Haskell and Common Lisp

#130
post #47

Earlier quoted context omitted.

I agree with you. I'm going to write a post about function application and composition (right-to-left / left-to-right) so other communities can stop discussing non-essential matters. I do like the fact that the `pipe operator` is often mentioned along the bash '|' which is used in a pointfree style. Well it might make sense sometimes, so its good to know one's options :) p x y z = f (g x y) z p = ((.) f) . g

Of course, something is very wrong if you ever use a section of the function composition operator. Use point-free within reason... :-p

Or go completely, absolutely nuts with point-free and use J (http://www.jsoftware.com/).
Post reply on HN