Asynchronous Programming in Functional Languages

asyncfunctional programmingside-effect

I'm mostly a C/C++ programmer, which means that the majority of my experience is with procedural and object-oriented paradigms. However, as many C++ programmers are aware, C++ has shifted in emphasis over the years to a functional-esque style, culminating finally in the addition of lambdas and closures in C++0x.

Regardless, while I have considerable experience coding in a functional style using C++, I have very little experience with actual functional languages such as Lisp, Haskell, etc.

I've recently began studying these languages, because the idea of "no side-effects" in purely functional languages has always intrigued me, especially with regards to its applications to concurrency and distributed computing.

However, coming from a C++ background I'm confused as to how this "no side-effects" philsophy works with asynchronous programming. By asynchronous programming I mean any framework/API/coding style which dispatches user-provided event handlers to handle events which occur asynchronously (outside the flow of the program.) This includes asynchronous libraries such as Boost.ASIO, or even just plain old C signal handlers or Java GUI event handlers.

The one thing all of these have in common is that the nature of asynchronous programming seems to require the creation of side-effects (state), in order for the main flow of the program to become aware that an asynchronous event handler has been invoked. Typically, in a framework like Boost.ASIO, an event handler changes the state of an object, so that the effect of the event is propagated beyond the life-time of the event handler function. Really, what else can an event handler do? It can't "return" a value to the call point, because there is no call point. The event handler is not part of the main flow of the program, so the only way it can have any effect on the actual program is to change some state (or else longjmp to another execution point).

So it seems that asynchronous programming is all about asynchronously producing side-effects. This seems completely at odds with the goals of functional programming. How are these two paradigms reconciled (in practice) in functional languages?

Best Answer

All of your logic is sound, except that I think your understanding of functional programming is a bit too extreme. In the real world functional programming, just like object-oriented, or imperative programming is about mindset and how you approach the problem. You can still write programs in the spirit of functional programming while modifying application state.

In fact, you have to modify application state to actually do anything. The Haskell guys will tell you their programs are 'pure' because they wrap all of their state changes in a monad. However, their programs still do interact with the outside world. (Otherwise what is the point!)

Functional programming emphasis "no side effects" when it makes sense. However, to do real-world programming, like you said, you do need to modify the state of the world. (For example, responding to events, writing to disk, and so on.)

For more information on asynchronous programming in functional languages, I strongly urge you to look into F#'s Asynchronous Workflows programming model. It allows you to write functional programs while hiding all the messy details of thread transition within a library. (In a manner very similar to Haskell style monads.)

If the 'body' of the thread simply computes a value, then spawning multiple threads and having them compute values in parallel is still within the functional paradigm.