A couple of months ago, we posted about the research program of SocioPLT, whose goal is to study why some languages get adopted more than others. As part of a study, the investigators ranked languages according to their frequency of use in Sourceforge projects during the period 2000-2010. An interesting finding was that among the top 20 languages in these rankings, there wasn’t even one functional language.
Academic PL researchers tend to love functional programming, so many of us would find this fact depressing. However, it seems that we academics are at least partly to blame for this state of affairs. For functional programming to be embraced in the “real world”, universities must teach it. In this post, I show that few universities do. In particular, functional programming is a significant part of the core programming sequence at only 9 of the top 33 American schools, and is not offered at all in about 40% of these schools.
Why functional programming?
There are good reasons why PL researchers like functional programming. In imperative languages like C, a line of code within a procedure can affect the entire global state of the program. In contrast, in functional languages, such side effects are severely limited. This makes it much easier to reason about correctness and security: analyzing the correctness of the composition of procedures A and B can be broken down into analyzing A and analyzing B. Researchers have also frequently argued that functional program design makes it fundamentally easier to exploit parallelism.
Why is functional programming unpopular?
So why is functional programming unpopular in the “real world”? Consider some non-reasons first.
The argument “functional programs are inefficient” isn’t really sensible any more (if it was ever). First, because of advances in compiler technology, implementations of functional languages are now more efficient than ever. As just one data point, in this comparison of two ray tracers written in C++ and the functional language Ocaml, the Ocaml implementation performed comparably with the C++ version, while having 47% fewer lines of code. Second, a survey of programmers by the SocioPLT researchers showed that a language’s performance was not among the top five factors when choosing it for a project.
The same survey also showed that the factor that correlates the most with preferring and using a language is the availability of libraries. This is certainly behind the meteoric rise of, say, Python. However, it seems implausible that this factor is the primary reason why functional programming is unpopular. If it were so, the F# language, which allows functional programmers to utilize the entire .NET infrastructure, would be a mainstream language by now. There’s no indication it will be any time soon.
The real problem: Education
By far the biggest issue with functional programming, it seems to me, is that most programmers aren’t familiar with this programming style. This is corroborated by a second survey from the SocioPLT folks, which reports that only 22% of the surveyed population were familiar with a functional language. Among participants who had “learned” a functional language in school, those claiming familiarity went up to 40% (an improvement, but still not impressive). In contrast, 94% of the participants knew at least one of C/C++, Java or C#, and 79% knew at least one of Perl, Python or Ruby.
The unavoidable takeaway from this is that university CS departments aren’t doing a good job exposing their students to functional programming. Even when they teach functional programming, the exposure is superficial enough to fade over time.
You ought to see this as a problem even if you aren’t a fan of particular functional languages. By programming in a functional language, a student encounters some fundamental insights: that data can be defined inductively, that many interesting applications essentially involve pattern-matching on data-types, that code is not fundamentally different from data, that keeping side-effects minimal makes composition easy, … These insights are useful even if you are going to program in Java or C++.
Who teaches functional programming?
So perhaps it’s worthwhile to investigate which schools do and don’t offer functional programming. Over at the CACM blog, Philip Guo recently posted about introductory languages used at the top 39 American universities (as defined by US News rankings). Only five of these schools used the functional language Scheme in their CS0 or CS1 course; “zero or one” used a statically typed functional language like ML or Haskell. Several of these schools have moved away from using Scheme to using Python. It’s clear from this data that few students learn functional programming in their first year in college.
But how many schools give their undergrads a serious exposure to functional languages, at any level? I couldn’t find this data anywhere, so I decided to do some quick digging. Below, I tabulate American universities ranked 1-30 in the US News 2014 computer science rankings, along with information about the first real functional programming course that they offer. For a course to be counted, it has to satisfy the following criteria:
- The course must require a substantial amount of functional programming. I define this as “30% or more of the assignments must involve functional programming.”
- The course has to be offered regularly. It must have been offered in 2013 or 2014.
- The class has to be reasonably general-interest. For example, Yale has a class on computer-aided music where students (apparently) do a good amount of Haskell programming. I wouldn’t count this course in my table. On the other hand, classes on compilers or programming language implementation that use functional languages are counted.
Classes that are required, or appear to be taken by a large number of students, appear in bold.
School | Course | Language | Type of class |
CMU | 15-150 | ML | Programming |
MIT | – | ||
Stanford | CS 240h | Haskell | Programming |
Berkeley | – | ||
UIUC | CS 421 | Ocaml | PL/Compilers |
Cornell | CS 3110 | Ocaml | Programming |
Washington | CSE 341 | SML, Racket | PL |
Princeton | COS 326 | Ocaml | Programming |
Georgia Tech | – | ||
UT Austin | – | ||
Caltech | CS 4 | Scheme | Programming |
Wisconsin | – | ||
UCLA | CS 131 | Ocaml, Scheme | PL |
Michigan | – | ||
Columbia | COMS W4115 | Ocaml | PL/Compilers |
UCSD | CSE 130 | Ocaml, Scala | PL |
Maryland | CMSC 330 | Ocaml | Programming |
Harvard | CS 51 | Ocaml | Programming |
Penn | CIS 120 | Ocaml | Programming |
Brown | CSCI 0170 | Scheme, ML | Programming |
Purdue | CS 456 | Haskell, ML | PL |
Rice | – | ||
USC | – | ||
Yale | CS 421 | ML | PL/Compilers |
Duke | – | ||
UMass | CMPSCI 220 | Scala | Programming |
UNC | – | ||
JHU | – | ||
NYU | – | ||
Penn State | – | ||
UCI | – | ||
Minnesota | CSCI 2041 | ML | Programming |
Virginia | CS 4610 | Ocaml | PL |
Conclusions
As we can see, several schools teach functional programming as part of their core programming sequence. For some of these schools (e.g., Minnesota), this appears to be a recent development. Of course, over the last few years, some schools (notably MIT, UC Berkeley and my home institution Rice) have also moved away from using functional languages in their core curriculum. I am not sure if the total number of schools that teach functional programming as part of their core programming sequence has gone up or down in recent times.
At some other schools, functional programming is taught in PL classes. This seems suboptimal, because I imagine that in most cases, these courses aren’t required. This may also tie functional programming too closely to the particular application of interpreter and/or compiler design. Of course, this is still better than not covering functional programming at all. Unfortunately, many of the schools, including high-profile schools like MIT and Michigan, don’t offer their students any exposure to functional programming.
How do we change this? Of course, university curricula are zero-sum games; in many universities, there just won’t be a spot for a new required programming class. One possibility, then, is to embed functional programming into lower-level required courses. I personally think that a course on data structures and basic algorithms could be a great vehicle for functional programming. Some schools already have a course of this sort. For instance, CMU’s data structures and algorithms course (15-210) was recently revamped to use only functional programming, with particular emphasis on persistent data structures and the exploitation of parallelism. Cornell’s CS 3110 is another excellent example of such a course.
It could also be nice to have more classes of the form “Functional programming for X”, where X is something other than interpreters/compilers and foundations of PL. In my research, I didn’t find too many classes like this. One exception is Purdue’s course CS 390, which is on parallelism and concurrency but uses functional languages for about 30% of the course. Another is Stanford’s course CS 240h, which teaches how to build system software using Haskell. But clearly, much more can be done along these lines. As examples, I’d love to see a course on data science using F#, or building secure-by-construction systems using Haskell!
[Caveat: I am by no means guaranteeing that the data I gathered is correct. If you find anything wrong with it, point it out in the comments, and the bug will be fixed.]
Nice and useful analysis! I think that it is critical for students to learn functional programming, which I would distinguish from learning a functional programming *language*. However, a functional PL is the right *vehicle* for that task. Once they’ve seen how to do it in ML, they’ll figure out how to do it in Java.
Except that it can’t be done in Java for lack of a conditional expression. I’m afraid the ecumenical approach, which has an understandable social appeal, does not actually work, and can’t be sustained.
At UCLA, I teach CS131, which spends half of the quarter on functional programming. E.g., in 2013, 4 of the 7 assignments use OCaml:
https://my.engineering.ucla.edu/classAssignment.php?term=13S&srs=187510200
My colleague Paul Eggert also includes Scheme when he teaches the course:
http://www.cs.ucla.edu/classes/winter13/cs131/homework.html
By the way, for UCSD you should use CSE130 — the course you’re citing is a grad course.
Also, our CS131 course is required at UCLA.
Duly noted!
UIUC requires CS421, Programming Languages and Compilers, which uses OCaml. Great article!
https://wiki.cites.illinois.edu/wiki/display/undergradProg/Degree+Requirements
Thanks! Sorry I missed CS 421 — I’ve fixed the bug now.
Your description of what we are doing is inaccurate and incomplete. The Python course is for non-majors only, and was a social compromise. A very few prospective CS majors start with it, but NOT because they have no prior programming experience, but only for those with a weak MATHEMATICAL experience preventing them taking 150 in the first year. The Python course is a stalling tactic that only impedes learning programming, in my opinion. It is not part of our introductory sequence for CS majors. 15-150 is designed for absolute beginners, who have a distinct advantage over those who think they already know about programming.
You should mention that our data structures and algorithms course was completely revamped to use only functional programming, with emphasis on persistent data structures and parallel programming throughout. See 15-210, designed by Blelloch and Acar, and the forthcoming text for it. It is the future of DS+A because it places proper emphasis on parallelism, and correctness and cost proofs for a parallel cost model.
So two of the four core courses in the intro sequence are entirely FP-based.
The other two are an introduction to low-level imperative programming using an ad hoc dialect of C, which feeds into the computer architecture/systems programming course. The well-known Ten Powerful Ideas in Theoretical CS course is prior to the intro sequence, and is what creates the scheduling conflict for a few less well-prepared students.
Bob: thanks for your comment. I’ve edited the post taking into account your feedback. Specifically, I have added some text about 15-210, which I think is an absolutely amazing course!
thanks. 150 and 210 are paired, with 150 feeding into 210. we teach proof of correctness and parallel cost from day 1 so that they are prepared for the new 210. it’s working beautifully.
Penn State has a programming languages course, CMPSC 461, and spends a large amount of time working with SML and Scheme. I believe 10 of the 13 assignments and 11 of the 15 weeks in the semester are devoted to these languages and their core concepts, but I graduated in 2012 so it’s been a while.
Great post. Not surprisingly, “who teaches functional programming” correlates strongly with “which institutions have faculty doing research in functional programming.” So the question is: how do we make inroads in to institutions where we have a less strong faculty/research presence?
Matthias Felleisen – the creator of Racket and HTDP teaches at Northeastern University, Boston. The undergrad Fundamentals to CS course is taught using Racket – http://www.ccs.neu.edu/course/cs2500f13/ and the graduate intro course Programming Design Paradigms (this is a compulsory course for all CS grad students) is also taught with Racket- http://www.ccs.neu.edu/home/wand/cs5010/ is taught by Prof. Mitchell Wand, author of Essentials of Programming Languages.
UIUC requires CS421 which is entirely over functional programming in Ocaml.
Apologies for the bug. It’s now been fixed.
“Unfortunately, almost half of the schools, including large, high-profile schools like UIUC and Michigan, don’t offer their students any exposure to functional programming.”
This is false for UIUC, You need to do better research before you make such claims.
Functional programming is not new at University of Minnesota. In my studies there in the late 1980’s, they were using Scheme to teach functional programming, and the class was a requirement for Computer Science majors. Only the current class using ML is new, introduced in 2013. I’d like to see schools adapt their functional programming classes to languages that are more likely to be used in industry, wherever possible. But does it really have to be a purely functional programming language that enforces pure functional programming? Why not use a multi-paradigm language, and teach students how to use it in a functional manner?
It’s worth noting that quite a few Universities in the UK, such as Oxford (Haskell) and Cambridge (ML) teach functional programming languages as first languages. In fact, in Oxford, the only programming language you will touch until the spring term is Haskell.
Great discussion!
At Penn, besides CIS 120, we also offer:
Compilers (CIS 341, uses OCaml, offered every other year)
http://www.cis.upenn.edu/~cis341/current/
and
Advanced Programming (CIS 552, uses Haskell, popular with undergrads despite course number)
http://www.seas.upenn.edu/~cis552/
I’d like to weigh in as a practitioner who also took functional programming courses as an undergraduate and as a grad student, including several years of programming in OCaml during my thesis work.
Let me begin by saying I agree with the main premise of this article: introducing functional programming languages during undergraduate CS curricula is absolutely valuable. However, it is neither necessary nor sufficient for adoption in practical settings.
Library is a major determinant in choice of language in industry. While F# and the CLR are no doubt wonderful technologies, though, the open source Java ecosystem (and the C++ and C ones that predated it) have always held the largest mindshare, and hence the widest library ecosystem, so I’m not sure that is a valid counterexample. I think the recent traction that Scala and Clojure have been getting in industry is possible partially because they can interact with that large body of open source Java code. Before that, I would have had a hard time recommending FP languages for projects, despite being completely comfortable with a number of them.
One major reason for the choice of Scala on a recent project was actually that the Scala syntax for the Akka actor system looked just like the pseudocode in a paper describing a distributed protocol we wanted to implement. Yeah, *syntax*, believe it or not.
Finally, good programmers can learn functional programming outside of an undergraduate setting. I work with a number of engineers who had no exposure to functional programming before their current assignment and yet have been able to come up to speed just fine; pair programming and code review can be very effective teaching tools. Could these engineers have benefited from being exposed to FP as undergrads? Undoubtedly.
“While F# and the CLR are no doubt wonderful technologies, though, the open source Java ecosystem (and the C++ and C ones that predated it) have always held the largest mindshare, and hence the widest library ecosystem”
Despite its origins as an MSR language, F# is now open (see http://fsharp.org/). Also, in my (admittedly limited) experience, F# runs just fine on both Windows and Linux (using mono for the latter). However, I haven’t used any of the more exotic CLR libraries so I can’t speak to that. Perhaps someone else with more experience could.
Similar to other schools on this list, Caltech’s CS1 (taught in Python) is not intended solely for CS majors, and is in fact taken by a massively large portion of the undergraduate student body. A sizable chunk of CS majors place out of it, and therefore never end up taking it.
CS115 is not the only functional programming course, and certainly not the earliest one. CS4 (which uses Scheme/Racket and SICP) is required of all undergraduate CS majors, and is usually taken by CS freshmen/sophomores. (Both classes are taught by Mike Vanier.) In our CS11 class, we teach a range of functional programming languages, including Haskell, OCaml, and Erlang, although these languages are usually taken by sophomores/juniors/seniors.
Thanks for the information! I have replaced CS115 by CS4 in the entry for Caltech.
Not all PL academics are functional programming fans; I would say that the object community is still going strong. As a UW undergrad, I had my first exposure to functional programming in CSE341 (Lisp, SML), but I was also exposed to real OO (Smalltalk). This actually led me to a lifelong love of objects, and I don’t think that was particularly unusual at this school (e.g. my TA at the time for CSE341, Dave Grove, still does object work).
The debate between what is better will definitely rage on; professional parallelism is still the domain of CUDA and other imperative systems (side effects can even be managed automatically!). The FP side of PL hasn’t won yet 🙂
I hope, however, that you agree that FP has key ideas to contribute and is worth learning for students, which is what the post says. It would be a surprising CS curriculum that didn’t expose students to objects, certainly.
I agree, but I counter that we aren’t really teaching them objects very well either given our poor excuses for OO languages, which just happen to be mainstream. Learning objects through a pure OO language like Smalltalk is eye opening even if you’ve been exposed to Java already.
I’m totally wedded to OOP and Smalltalk, as well. It doesn’t matter whether FP is “superior” to procedural programming (it’s highly debatable). The world is immersed in OOP and that won’t change for generations. Concurrent programming will continue to be a niche in IT for decades, so where is the win for FP? I just don’t see it.
There’s now a rather active Reddit thread on this topic: http://bit.ly/YbdKM8.
As a practitioner who was once enthused by FP, I would argue that functional languages are very ill-adapted to solving many common problems, which is why they aren’t very much in use. I spend much time writing application servers where side-effects are the whole point.
Usually, my program is attempting to connect to other services over a network, store and retrieve data from a database, manipulate files, etc… All of those operations are hard to do in purely functional languages. Now you could argue that those operations can be isolated which would mitigate the difficulty of writing such systems. However, side-effects are not just isolated to the edges of my program. Everywhere, instrumentation demand that I update some global state, such as request counters, latency trackers, log files, etc…
The way I see it, functional languages aren’t used much because they make common tasks hard. Now, teaching FP to students is probably a good idea. I aim for small composable functions with few, if any dangerous side effects whenever possible and encourage such a style in people whose code I review. But the idea of switching to a purely functional language such a Haskell for real work sends shivers down my spine.
On a side-note, library support is not just about supporting a particular common library or framework. It is also about the myriad of third-party libraries which one depends upon when writing code in a specialized domain. Even if there are equivalents in the language, they have probably received less attention.
As far as I am concerned, the language selection process is best handled with a single question: “What is the language most likely to help me achieve my goal?” The answer to that has never been a functional language, except when trying to learn FP in my spare time.
The standard irrefutable argument is always “that’s all very cute, but it isn’t applicable in MY domain”. Yet over decades these assertions have been knocked down, over and over. A fine example is the Ensemble suite of network protocols — what could be more I/O-intensive than that? Two developers started simultaneously to build the same functionality (Hayden and van Rennesse). The student, Hayden, finished in two weeks, before van Rennesse could get his shoes on, and the resulting code was smaller, faster, had fewer bugs, and was far easier to maintain and evolve, and took far less time to build in the first place. As another example, Nikhil was doing functional databases back in the early 1980’s; what is SQL if not an extremely crappy functional language? Jane Street does high-frequency trading, utterly performance- and I/O-intensive, entirely in ML. There are by now thousands of examples that “can’t be done in a functional language” that are, in fact, done far better in a functional language.
To equate “functional programming” with Haskell is to confuse marketing with reality. Although you didn’t mention it, others have equated functional languages with laziness, which is not accurate (Haskell is the locus classicus of that mistake). Others have equated functional programming with the fragment of modules that are provided in Haskell, also not representative of functional programming. Here you’re equating functional languages with the inability to make use of benign effects, such as instrumentation of code for profiling purposes, which is indeed very clumsy in Haskell (you either have to rewrite your code to be imperative so that it conforms to the IO Monad, or else you have to admit that you really want ML by using unsafePerformIO). But such things are straightforward in ML. My point is that it’s hard to make statements about “functional programming” when there are such broad differences between its realizations in various languages, advertising and hype to the contrary notwithstanding.
I must confess I am unfamiliar with ML. So it is possible that my understanding of FP is primarily influenced by my exposure to Haskell. That said, I never said such things are not possible in functional languages. However, my understanding is that the benefits of functional languages accrue by writing side-effect-free functions. If side-effects are your bread and butter, you can see how one would expect FP to be a bad fit.
Right, I understand. That’s why I mentioned Ensemble, for example, as something that one might well have thought “obviously” cannot be a good fit for a functional language. And yet it was superior in all dimensions to C++ code written by an expert!
It’s also readily understandable that people new to the field equate functional programming with Haskell, but that’s just marketing. People equate cola (or, in the American south, any form of soda) with Coke, and tissue paper with Kleenex, and bleach with Clorox. The trouble is that it is then easy to draw inferences about functional languages that apply only to the one brand.
I share your view 110%. FP makes common tasks harder. It’s much easier for me to think procedurally than functionally. But that’s probably because I grew up with procedural programming. I’ve tried to get into FP several times, but I always lost the will to follow through; it’s hard when you’ve already been indoctrinated. And that’s the obstacle that will prevent FP from becoming mainstream.
Pingback: Programming Issues, 9월 1주 | Tinkering Driven Life
At Saarland University in Germany, Standard ML is being taught as first language for new students in the “Programmierung 1” course, and Java is only encountered in the second term for the “Programmierung 2” course.
Pingback: F# Weekly #39-41, 2014 | Sergey Tihon's Blog
Pingback: 미국내 상위대학에서도 함수형 프로그래밍을 가르치지 않는 현실 | 한국 HTML5 Lab
UC Berkeley teaches Scheme! http://www.cs61as.org/
We have added (back) a functional programming course at Rice: Comp 311. The language used is Scala. Online materials are available at http://comp311.rice.edu
I’m now on my second iteration of teaching Haskell in the intro programming course at ANU to 450+ students (including a large fraction of non-CS-majors) and starting to be a believer. Coming off previously using Java in my first-year course for CS majors at Purdue I’ve found communicating fundamental concepts much easier in the functional context. I found particular inspiration in CMU’s revamped intro ML sequence (though I’d like to introduce more of that material on parallelism and performance, which might mean switching to ML) and Penn’s CIS194 has also been very helpful (thanks go to Joachim Breitner). I inherited Haskell as the medium so laziness does get in the way of communicating cost models to students. But the Haskell ecosystem turns out to be great. Using a modern IDE (IntelliJ+Haskforce) is part of the attraction. It’s interesting how much of a difference that makes to students these days. The second course in ANU’s sequence is Java in the large with IntelliJ, so our first years end up very well rounded.
Cool! Thanks for sharing!
I recently offered to teach FP/Scala at two local CT universities that had *no* FP coursework. There was no interest at all. You could argue that it was me 🙂 since I’m not an academic. But in that case, I thought there would have still be interest in the idea. Empirically, the growth of Scala and its adoption in the business world (it is all over wall street and the NY financial industry these days) would argue for at least some initial interest from local universities. I’m curious if you’re planning to update this survey? I’d be interested in new (2017) results.
Pingback: Teaching Programming Languages - The PL Enthusiast