I currently code with C, C++, and Python. I'm wanting to pick up a functional programming language, and right now I'm leaning toward Haskell. I do NOT want to start a "Haskell vs Lisp" war here; what I want to know is this: if I learn Haskell primarily for exposure to functional programming, what benefits, if any, will I gain from later learning Lisp?
I suggest learning both, Haskell first, then Common Lisp. My experience with Haskell was that the static typing seemed to be a restricting annoyance at first, but once I got used to it, I noticed that most of my type errors had logic errors hiding behind them. When you get to this point, and the next milestone, which is learning to think in types and define your own types as a means of expressing your solution, you'll be ready for Common Lisp.
With Common Lisp, you can add monads, currying, and everything you liked from Haskell, but you also get multiple inheritance like Frank Shearar mentioned, and generic functions with multiple dispatch, and an advanced exception handling system.
So why not just learn Common Lisp first? Coming from a procedural and OOP background, my experience has been that I didn't really understand functional programming until I had to use it exclusively. Once functional programming is comfortable, you can add the rest of the tools that Common Lisp makes available, and use whatever tool is best at the task at hand.
Haskell teaches you the purest of FP, as far as I'm aware at least, just like Smalltalk teaches the purest of OO. (I mention this not to suggest that OO and FP can't marry, but because both these languages are "gem" languages - a core idea taken to extremes.)
Lisp is really a family of languages, so I'll talk about Common Lisp because that's the particular member of the family I use.
Lisp will still have lots to teach you:
- It's multiparadigm, so as dsimcha points out it'll show you how to integrate FP with other paradigms.
- Lisp will teach you that "code-is-data, data-is-code", for example through its macros.
- CLOS is a very interesting brand of OO, with multiple inheritance that works, and generic functions.
Haskell and Lisp are two totally different beasts.
Haskell is kindof "pure functional programming in an ivory tower"
Lisp is kindof "code-is-data / data-is-code / make your own language constructs". You can manipulate your code in whatever way you can imagine.
They are very different. Both share the "functional programming" aspect, but that's really a tiny little common point compared to their differences. Just try them out and you will see how different they are!
I also come from a C/C++/Python background and have tried out FP a couple of times in the last few years. Initially I looked at Haskell and couldn't make head or tail of it, then tried Ocaml but didn't get much further with that. Finally I started hearing good things about Scala, tried it, and found it suited me very well (I had also done a bit of Java in the past), to the point that after a year of so of dabbling in Scala (and dispatching 161 Project Euler problems with it), Haskell seems to make much more sense. In fact I just ordered a couple of books on Haskell and want to give it another go, although this is largely motivated by the existence of Scalaz.
So I found using a multi-paradigm language (ie Scala, but Lisp would probably fit the bill too) a good way into FP. But if you're happy diving into Haskell (I wasn't), go for it.
I originally came from a C/C++/Ruby background and I used FP concepts in Ruby whenever I could. State just kinda hurt my brain. One of my buddies called me up one day, and he asked me to write something in Haskell (my first - and hopefully not last - Haskell job!). I quickly learned the language and I threw together something that worked. It wasn't beautiful or anything, but it worked.
I took a month break from Haskell because I didn't have anything to use it for. But when I decided I needed to write my own blog software, I used Haskell (https://symer.io). Haskell is really cool because you can break a problem into parts and implement these parts differently based on input. Haskell also handles failure extremely well through intelligent boxing of values. There are so many tools to work with these boxes that you simply forget they exist.
C++ can't hold a candle to Haskell, outside of memory management. Haskell is just as fast (if not faster), significantly more terse, and much more safe. But Haskell's safety never gets in the way.
TL;TR Haskell is a breath of fresh air, and Lisp is a slightly more functional Ruby.