Question

I have read a lot of threads about functional programming languages lately (almost in the past year, in fact). I would really like to pick one and learn it thoroughly.

Last [course] semester, I have been introduced to Scheme. I loved it. Loved the extreme simplicity of syntax, the homoiconicity principle, the macros (hygienic and non-hygienic), the n-arity of procedures, etc.

The problem with Scheme is it's an academic language. I don't think it is really used in production environments. I don't believe either that it is particularly good to have on our resume. So, I have been looking around for alternatives. There are many of them and they somehow all seem to have a similar level of popularity.

Some thoughts about some other functional languages I have considered yet:

  • Clojure: It sounds great because it can access the Java world, it is oriented towards scalability and concurrency, but isn't the Java world on an edge right now? I already know Java pretty well, but would it be wise to add even more energy on depending on the JVM?
  • Haskell: Looks like a very appreciated language, but from what I have read, it's also more of an academic language.
  • Lisp: It's been around since forever. It seems to have most of what I like from Scheme. It has a big community. For what I [think I] know, it is probably the most widely used functional programming language in industry(?).
  • F#: Didn't really consider it. I'm not a big fan of MS stuff. I don't have the money to pay for their softwares (I could have them free from university alliances, but I'm more inclined to go with community-driven solutions). Though... I guess it would be the best career-oriented choice.

Tonight, I'm leaning towards Lisp. One week ago, it was Haskell. Before that it was Clojure. In the past year, I was doing some Scheme for fun, not pushing it for the reason you know. Now I would like to get serious (about learning one, about doing real projects with it, about maybe eventually professionally working with it). My problem is I would need to learn them all in depth before being able to choose one.

Was it helpful?

Solution

Since you want a practical  language:

alt text

Notice that Haskell and Lisp are used more than the others in industry, although there has been some recent interest in Clojure and F#.

But look what happens when we add Scheme to the mix:

alt text

Hmm, doesn't look so much like an academic language now, does it?

Actually, the above graph is probably a lie; the word "scheme" can appear in help wanted ads in other contexts besides programming languages. :)

So here is another graph that is probably (a little) more representative:

alt text

If you want to explore a really kick-ass dialect of Scheme, have a look at Racket.

OTHER TIPS

If you want to learn functional programming, you might be better served to learn Haskell first, then use whichever language you want. You can learn functional programming using the other languages, but they still allow for imperative and object-oriented code. If you write a real program in Haskell, you will learn functional programming faster because the other paradigms won't be available to fall back on.

After writing your Haskell program, you will have tools like monads and techniques like point-free coding to bring to the language of your choice. The concepts seem to map especially well to Scheme.

Actually, if you were able to implement a reasonably complex system in Scheme, you'd be fairly desirable at companies where you'd probably want to work. Earlier in my career I ran into some students who had done a fair amount of work in Scheme, and the only time it was a disadvantage was when they were unable to explain their work or didn't actually understand it well enough to implement basic data structures and algorithms within a reasonable amount of time. I always let candidates answer such questions in their preferred language; I did run into some people who thought that they were best at Scheme who managed to struggle quite a bit with things that should be easy, like adding an element to a linked list, which mystified me.

But if you were able to "get" Scheme well enough to write even an average web app, that would be a pretty good selling point at most serious software companies.

If you were interviewing at a "blub" shop and the developers just thought you were weird because of your proficiency at Scheme or Haskell or F#, you probably wouldn't want to work there. In most cases, competent developers get their choice of gigs, so don't sweat "practicality" unless the only options you can imagine in your future are corporate. Work on being competent, flexible, and breaking down problems.

College isn't about practicality. It's about creating a safe environment to explore and learn. That is, in fact, useful, even if you end up writing ordinary software for the rest of your career.

That being said, I don't see why you'd want to limit to just one of those choices so soon. You could easily get a sense of all four of the languages in about 4 weeks, then pick one to concentrate on that meshes best with your current whims. Then go back to another one of your options and try to implement something similar. Move on to something more complex, and consider your options again. Experimentation is good. Unless you're trying to make a living next month, you don't need to become a specialist yet.

I've written some in Scheme, F#, Emacs Lisp, and Common Lisp, and read at least a bit of Haskell, at least occasionally over the last few years. I can't say I'm an expert in any of them, but each excursion into those languages has benefited me in all the other languages that I work in professionally (C#, Java, Ruby, and occasionally Boo, Perl and Python). Curiosity will build you a more enduring, fulfilling career than anything else.

I dove into Haskell for a while, but the conclusion I came to was that it was a little too academic. It was very hard to do anything practical. In a pure functional language, things like IO just don't quite fit into the model, so you have to deal with monads. I determined I would have to put in a tremendous amount of time to be just barely competent, so I moved on.

I did Scheme in college. Might sound trivial, but all the parens really are distracting/annoying. Hard to go back to that after using languages like Python.

Recently I have been exploring F#. It is functional, but can also be imperative and object-oriented when you want to. This, along with being able to use any .NET libraries, makes it possible to easily mix your pure functional parts with more practical things like GUIs, IO and networking. You can get a standalone version of F#.

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=effc5bc4-c3df-4172-ad1c-bc62935861c5&displaylang=en

I evaluated all the major functional languages a year or two back, from the perspective of wanting a practical, general purpose functional programming language.

I ended up picking Clojure, which has subsequently proved to be an excellent choice.

Broadly speaking the key reasons were:

  • Library ecosystem - for a language to be useful, you need access to good libraries. Being on the JVM means that you have easy access to the largest open source library and tool ecosystem, so going for a JVM language was a no-brainer from a pragmatic perspective. Scala also scored highly here.

  • Macro-metaprogramming - This aspect of Lisp always appealed to me, especially since I anticipated doing quite a bit of code generation. I've very much appreciated the arguments made in Paul Graham's short essay "Beating The Averages". The various Lisps all scored strongly here.

  • Performance was "good enough" - Clojure is always compiled and gets the benefits of the JVM JIT optimiser and excellent GC. As always, there is some overhead in using a functional language but with Clojure it was clear that you can each close to Java speed with a bit of effort (Clojure supports Java primitives and optional static typing for those situations where you need it). My estimate is that Clojure is ballpark 2-5x slower than what you could achieve with optimised Java or C++ code, which is consistent with what you see in the flawed benchmarks, and over time I expect that gap to narrow further. Also, it's easy enough to just write particularly performance-sensitive code in pure Java and call it from Clojure.

  • Concurrency - Clojure has a fairly unique and powerful approach to concurrency, particularly for highly multi-core concurrency. It's a bit hard to explain, but this video is excellent to give a taste of the principles. I think Clojure currently has the best answer to the tricky question "how should you manage shared, concurrent and mutable state in a functional programming language?".

  • Language design - Clojure is IMO a very well thought-out language design. Examples are having vector [] and map {} literals in addition to the regular Lisp parentheses, use of immutable persistent data structures, supporting laziness throughout the language via the sequence abstraction, and providing the programmer with a variety of orthogonal features to solve different problems. See the art of abstraction and simple made easy.

  • Community - always subjective, but I liked what I saw in the Clojure community. The attitude was very helpful, constructive and pragmatic. There is a strong "get things done" emphasis, possibly reflecting the fact that a lot of Clojure people (including Rich Hickey himself) come from a background of building complex enterprise systems. The fact that the Clojure community has strong links into the Java community as well was important in convincing me that Clojure wouldn't run the risk of getting stuck in a "niche".

If I had to name a couple of minor downsides of Clojure, these would be:

  • Dynamic typing - often this is an advantage in terms of productivity, but on average I think I'd trade this for stronger type checking and inference. Mostly this gets mitigated by having a good automated test suite, but if you like your types statically validated by the compiler then Haskell or Scala may be more your cup of tea.

  • Cutting edge - Clojure is developing very fast and there's a lot of innovation going on - the downside of this is that there is a lot of experimentation, some libraries and tools are still immature, and there are occasional breaking changes between Clojure major versions that you need to keep an eye on.

Overall though, I don't think you can go wrong with Clojure if you want an excellent and pragmatic modern functional language!

It looks like you've done your homework, so you probably already know this, but Scheme is a dialect of Lisp just like Common Lisp is. If you like a lot of things about Scheme, but don't like its academic nature, try Common Lisp. According to the TIOBE index, it's the 13th most popular language vs Scheme at position 26.

Few of the languages you've mentioned appear on the job descriptions I've seen recently, though that might just be my small sample set. I personally will be learning Haskell, even though I don't expect to use that language directly in my job. The concepts of functional programming are more valuable to me for future program designs than the direct marketability of the language itself.

Licensed under: CC-BY-SA with attribution
scroll top