QCON SF: return of the fundamentalist functional programmer
While attending QCon San Francisco, I had the particular pleasure of attending a whole track that was devoted to the area of functional programming, a topic that I have a profound interest in. After having followed the track, I'm even more convinced than before that functional programming is not confined the the academic world. I think that it will have a profound impact on our mental perspective and the way we think about programming and problem solving in the next coming years. In this blog, I will summarize the sessions I followed, provide you with a couple of thought provoking ideas that I picked up, and hopefully makes you think about your programming style.
The track started of with what seemed like a rather unusual combination: a presentation by Paul Hudak about Haskell and the Arts.
He talked about the concept of Functional Reactive Programming (FRP), now a key area of research at the University of Yale. FRP is a programming style where each function can capture a time varying quantity (for instance input sound, video, user actions). This style of programming has applications in Robotics, parallel programming, audio processing. Whenever a new input value is given to a function, it is re-evaluated and new output is returned. In his talk, he presented specially HasCore and HasSound, domain specific languages developed for music and sound synthesis. Paul said that functional languages are specially suited for computer music, as they are declarative (saying 'What' should be done, instead of 'How' it should be done). Haskells abstraction mechanisms allow for musical programs that are elegant, precise and powerful, using the mechanisms of lazy evaluation, higher order functions, algebraic data types and type classes. A basic example of music modeling in Haskell can be found here.
The next talk was given by Lennart Augustsson on a very different subject, yet no less interesting: implementing Domain Specific Languages in Haskell. It seams that, whenever the topic of DSL's is mentioned to a Haskell programmer, a wry smile will appear on his face, since this has been done since ages in Haskell already, and it's hard for him to see why it's currently such a hype.
Lennart gave a couple of examples which he himself had developed by implementing DSL's in Haskell. For me, the most striking was the case where he had implemented a DSL for generating Excel (i.e. the real Excel sheets, not just a text based csv file). As he stated, Excel has a somewhat rudimentary abstraction mechanism, consisting only of copy and past re-use. However it is used widely by business people and is a familiar UI. Therefore, the solution is to generate Excel sheets. Lennart is an advocate of strong type checking to prevent errors at compile time. He showed how he had used Haskells type classes, and also a more obscure concept as Phantom types in his Excel DSL. The result was a DSL capable of generating Excel sheets without allowing type errors in operations, such as the addition of two cells in Excel where one contains an integer and the other containing a string, a thing that Excel itself does not prevent. An interesting and also amusing session indeed, showing the full power of Haskells type system capabilities, and demonstrating a use of it in an area that probably does not spring directly to the mind when thinking of Haskell.
A perhaps more familiar concept to most of us was demonstrated in a session given by David Pollak . He talked about a web application, Buy a feature, that he had developed recently. A subject that perhaps will not raise most interest immediately, however, David had used Scala and Scala's Lift web framework, the latter being created by himself. He had been using functional programming paradigms, including Scala's Actor library to deal with concurrency, in order to implement a multi-user, web-based, real-time, serious game. As he stated, the team initially used the Java's imperative programming style. However, after some time (and coaching) they gradually move over to use the declarative, functional programming style that Scala also offers. Some more noteworthy statements were, that none of the bugs found in the application were concurrency related, apparently the event driven, message passing programming style using Scala's Actor library served him well.
Also, he stated, the amount of unit tests he needed to comfortably put this system into production had been considerably less (in the order of 30% if my remember correctly) compared to the amount of test coverage required when using Ruby and Rails, which he has also been using extensively. An interesting case study, and one of the first real world examples about Scala's usage that I had heard of. If you're interested, read David's blog) for more on this topic.
The day's ending could not have been much better for a functional programming adherent.
Eric Meijer himself concluded it, with a delightful talk titled 'The fundamentalist functionalist programming'. His thought provoking argument is that we've been moving into the wrong directions for the last dozens of years in the way we program, and it's time to see change direction. Turning, as the title of this blog indicates, to pure, fundamental functional programming.
Why would this be a good thing? All 'pure' functional code has no side effects, and therefore does not alter state. Lacking state that is altered, the order in which statements are executed does not matter, nor does number of times a program gets executed. This makes programs better understandable and far less error prone. How nasty an implicit side effect of a function can be was shown by Eric with an example from the C# language. It would make this blog too lengthy to go into detail, so for the interested reader should take a look at his blog.
Now, many will think along these lines: 'no side effects, thus, no use', specially when thinking about how to do IO, which always causes some side effect. Actually Eric's main argument about fundamentalist functional programming was not that all side effects are bad. Indeed he argued that any program can have side effects, and that side effects are even a good thing. However, his main argument was that all side effects should be made explicit in the language. It's the implicit side effects hidden in function or method calls that leads to surprising and unexpected results and as a consequence lengthy debugging sessions. Even Erlang is not a 'pure' functional language in the fundamentalist sense, since IO operations as well as the spawning of a new process do have side effects that are implicit in the language.
The language Eric has taken part in designing, Haskell, is naturally the language he is advocating to use, and if not the language itself, then at least its ideas. In Haskell, all side effects are coded in Monadic classes. Eric gave a simple example about this concept, stating that a Monad can be simply be understood as a Collection of values of things that change. He made the comparison of a watch being a Monad, of which the time has a different value each time you take a look at it. The watch does not change itself, but the value it represents does. Monadic classed can be passed around functions without letting side effects escape the Monadic class itself. By using this mechanism, it is immediately obvious which parts of a program actually do change state, and this makes programs easier to understand.
One might think that these concepts are still only of academic interest. However, as Eric showed, it's already out there in LINQ, .NET's language-integrated query, set, which uses Monadic classes and lazy evaluation. So if you if you're a C# programmer, you're already dealing with these functional concepts. C# incorporates more and more functional features into the language.
A very thought provoking talk that made me think why the whole world is not using a functional programming style. However, after this day, I'm convinced that functional programming is very much alive, and we'll see an increasing use of it and its ideas in our daily work. I think we need to embrace those ideas to take full advantage of them in our problem solving and, ultimately, to write better programs.