I am trying to learn Haskell, and I really like it, but I can't wrap my head around most of it. Would Lisp, OCaml, etc. be a gentler introduction to functional programming?
This is a fairly subjective question so enter a subjective answer :)
I find that Scheme is usually the easiest way to introduce people to functional programming. It's taught in many colleges and there are many tutorials available online. From my usage it appears to be a simpler language that is easier to grasp than full out Haskell.
As JaredPar said, this is obviously subjective, but I think SML is a good language to start with. It's 100% functional (unlike something like Python which allows you to do write more or less functional code, but also makes it easy to fall back into the old imperative habits), and I think it helps that it's such a clean and well-defined language. Haskell has a lot of bells and whistles that aren't essential to understanding functional programming, and which may prove distracting.
I'm not sure about Scheme. It's a nice language, and it is very small and simple, but I mentally categorize Lisp and Scheme in their own little world, clearly related to functional programming, but not quite the same family as other functional languages. As such I'm not sure how well it works as an intro to functional programming.
I first learned functional programming through Scheme, but I'm not sure I'd recommend the experience to someone else if they don't have teachers and exercises available (if you are set on it, you can check out these slides, which were done by students for students, in commemoration of another class that is no longer taught at that university.) Be sure to ask for a lot of help; there's also a nice online tutor linked to on that page which you can do simple exercises on.
Functional programming consists of a lot of parts, and if you don't grasp monads or functors in Haskell, that's OK: you can still the finer parts of recursive and functional thinking without them. If you haven't been learning out of Real World Haskell, I strongly recommend it now. One of the trickier bits is learning both Haskell's type system and functional programming at the same time, which are both fairly novel to programmers.
Haskell is indeed an ambitious place to start. Here's some commentary on functional languages:
For Scheme there is excellent beginner reading matter and software. But Scheme, like Lisp, is different from other functional languages: the community is splintered; a frighteningly sophisticated macro system is necessary; what type system is there doesn't help you program; and there are no algebraic data types or pattern matching. Scheme is also unfriendly to currying and partial application.
Summary: you can learn a subset of functional ideas very well, but it's hard to get to the really interesting stuff.
Standard ML is frozen in amber, but there are still good implementations and good books. Bob Harper and Mads Tofte have posted free notes online. You get algebraic data types, pattern matching, and a type system that offers type inference but that you still have a chance of understanding. My favorite implementations are Moscow ML and MLton. Unfortunately, Moscow ML's library is out of date.
Summary: good functional mindset, and you get all the important basics, but limited libraries and user community.
Objective Caml is an ML dialect defined by its implementation. It appeals strongly to C programmers; the compilation model is quite C-like, and the libraries have a strong imperative flavor. Example: Caml is the only functional language I know in which all strings are mutable. Caml has a vibrant user community, but the language itself is tightly controlled by a small group at the French national lab INRIA. Jason Hickey has a nice book online. Caml is not to my personal taste, but many people are wildly enthusiastic. And the compiler is very well done.
Summary: the least surprising functional language for C programmers.
Haskell is the functional language for people interested in new ideas. Every year they pour new stuff into the major implementation, and there is an amazing community doing stuff from music to graphics to type systems to window managers to parallelism. Haskell has everything including the kitchen sink, and it will be hard to learn on your own. But before giving up, you might try the Helium compiler, which is designed for those learning Haskell.
Summary: Haskell has the most and best and newest ideas, but even though people are trying to help you, Haskell will probably make your brain hurt. In a good way!
Erlang has been used largely in telecoms applications, where it is a major success. It lacks a static type system but does provide pattern matching (which I consider essential to the functional experience). People I trust have told me that Erlang is as much about "parallel-and-distributed" as about "functional". I wouldn't recommend Erlang for a beginner.
Summary: Interesting, but in 2009 still a niche language.
F# is a new player, taking the Caml core and integrating it into the .NET type system. The minds behind it are really good, and I expect great things, but I'm not sure there's enough critical mass to support beginners yet.
Summary: worth keeping an eye on, especially for .NET programmers.
Many people on this forum also like Clojure; to me it looks derivative: primarily about new implementation rather than new ideas. For that reason I haven't informed myself very well.
Overall recommendation: Have another go at Haskell via Helium, and if that doesn't help, try Standard ML.
Use "Write yourself a Scheme interpreter (in Haskell) in 48 hours" - this way you'll learn something about scheme and haskell in the same run
I found this very gentle introduction to functional programming and more. Computer Science 61A - The Structure and Interpretation of Computer Programs http://webcast.berkeley.edu/course_details_new.php?seriesid=2008-D-26263&semesterid=2008-D
by Brian HARVEY from UC Berkeley. He uses a simplified version of Scheme.
Since you are looking for lisp, you might want to try Clojure. It is nice little functional lisp dialect that runs ot the jvm.
I found it much cleaner, simmpler and mose consistent then Haskell, but this is of course subjective.
Scala might be a good introduction. It's a functional and object orientated language that compiles down to Java byte codes and has access to all the Java libraries. This is a big win as most functional languages (other than F#) tend to have poor 3rd party library support.
There are plugins for Eclipse and NetBeans to make like easier, if an IDE is your thing.
Try harder.
The point of Haskell is that it pushes you into purely functional programming by taking away side effects.
At first when you try Haskell, it seems ridiculous that any software could be written this way. But if you try hard enough and actually write some code, at some point you'll "get it" and see that you actually can get things done in a purely functional way, although it often remains a challenge.
None of the other mentioned languages do this, as they allow you to mix in side-effects quite freely.
Erlang is nice though, being half-pure and concurrent and all.
Functional programming is essentially about:
- Learning a style of programming that is side-effect free
- Learning to write programs using recursion rather than iteration
- Learning the benefits of having functions as first class objects
A very good case can be made for learning Scheme, although I would argue that Common Lisp is also suitable as a gentler introduction to functional programming. I would recommend learning Common Lisp with Paul Graham's book, ANSI Common Lisp. Common Lisp will grow with you as you become more proficient, whereas with Scheme I find that I tend to be locked into a particular implementation.
With all the (R5RS-compliant) Scheme implementations I've tried (admittedly, a while ago), I've had to use different syntax to include SRFI libraries, and not all Scheme implementations implement all SRFI libraries. This results in not-quite portable code. Things may have changed with R6RS, but I have not yet found a good reason to return to Scheme.
Statically typed functional languages do make a compiler writer's job easier because they are designed to be easier to compile to efficient code. Sometimes the extra syntax helps you identify a coding mistake early, sometimes it is a bit of a hindrance. I also find that a lot of complexity is introduced into the language as a result of providing type-safe language features.
I think I can understand how you chose Haskell. Simple Haskell code looks very beautiful and elegant but as soon as you start using the intermediate to advanced features of the language such as strict evaluation and monads, it starts to look less so.
Haskell is a good language to return to later. SML, OCAML and especially F# are good languages for software engineering. However, to learn functional programming (and for other good reasons), I would recommend Common Lisp and it is not difficult to learn at all.
Peter Seibel, author of "Practical Common Lisp" (available free online), wrote (and I'm paraphrasing a little) that although a very proficient Java programmer he found that while learning Lisp he felt that he was more productive writing Lisp code, despite frequently having to consult Lisp documentation to about various Lisp functions. This may be marketing blurb, but I would agree.
I personally recommend Lisp. Elisp is accessible via the emacs editor, and Common Lisp is available as an open-source project. Of course, Scheme is a dialect of Lisp. One of the great advantages of Lisp is that it is unambiguous to parse for a human(although the parentheses can scare people).
F# may become the best choice in years to come, but I've found an appallingly wide gap between the "hello world" tutorials and the advanced discussion. I think it's worth keeping an eye on.
Like you, I've found Haskell hard to work with, and I've found the tutorials largely to have a bad attitude. Meh.
Go with Lisp. It's the future. It's been the future for 50 years. ;-)