TITLE: StrangeLoop 3: Functional Programming 1 -- Monads and Patterns AUTHOR: Eugene Wallingford DATE: September 26, 2012 8:12 PM DESC: ----- BODY: The StrangeLoop program had a fair amount of functional programming talks, and I availed myself of two to complete the first morning of the conference. Monad Examples for Normal People The web is full of tutorials claiming to explain monads in a way that anyone can understand. If any of them had succeeded, we wouldn't need another. How could I not attend a talk claiming to slay this dragon? Getz started out with a traditional starting point: a sequence of operations that can be viewed as composition of functions. That works great for standard business logic. But consider a common exceptional case: given a name, looking up an account number fails. This requires us to break the symmetry of the code with guards. These break composition, because now the return type of the function doesn't fit. The Maybe monad factors these guards out of the business logic. If we further need to record and capture error coded, we can use the Error monad, which factors the same sort of plumbing out of the business logic and also serves as a facade for a tuple of value and error code. After these simple examples, the speaker dove into the sort of exercise that tends to lose the interest of programmers in the trenches building apps: building a Lisp interpreter in Python, using monads to compose the elements of the interpreter. The environment consists of a combination of the reader monad and the writer monad; the interpreter consists of a combination of the environment and the error monad. Several other monads play a role in representing values, built-in procedures, state, and non-standard control operators. An interpreter is, he said, "monad heaven". The best part of this talks message was in viewing a monad as a design pattern that abstracts repetitive plumbing out of applications in such a way that preserves function composition. After the talk, someone asked a question to the effect, "I get by fine with macros and higher-order functions. When do I need monads?" Getz answered from his personal experience: monads enable him to write more elegant code, by factoring repetition that other tools could not reach as nicely. This wasn't the monad explanation to end the need for new monad explanations, but it was a decent effort. With the Getz's focus on factoring code and the question mentioning macros, I could not help but think of this essay that presents monads in the light of code transformation, and Brian Marick's approach treating a monad as a macro. Perhaps we are getting near a metaphor for monads that will help "normal people" grok them without resorting to abstract abstract math. Functional Design Patterns From the moment I saw the StrangeLoop line-up, I was excited to see Stuart Sierra speak on functional design patterns. Sierra is one of the few prominent people in the Lisp and Clojure worlds to acknowledge the value of design patterns in functional style -- heck, even to acknowledge they exist. He opened his talk in a way that confronted the view commonly held among Lispers, He conceded that, for many, "design pattern" is a loaded term, bringing to mind an OO cult and the ominous voice of the Gang of Four. The thing is, Sierra said, Design Patterns is a pretty good book, given the time it was written and the programming language community to which it. speaks. However, in the functional language community, the design patterns in that book are best known for being debunked by Peter Norvig in a 1998 tutorial. Sierra reminded this audience that patterns can occur at all levels of a program. He pointed to a lower-profile patterns book of the mid-1990s, Pattern-Oriented Software Architecture (now a five-volume series), which organized patterns at multiple levels: Sierra then went on to list, and describe briefly, several common patterns he has noticed in functional programs and used himself in Clojure. Like POSA, he organized them into categories. Before proceeding, he admitted to any Haskell programmers in the room that, yes, many of these patterns are monadic in nature. I'd very much like to write about some of Sierra's patterns in greater detail than a single entry permits, including providing links to blog entries he and others have written about them. For now, let me list the ones I jotted down, in Sierra's categories: Before describing Reduce/Combine, Sierra took a short digression to talk about MapReduce, a pattern accepted by many in the world of big data. He reminded us that this pattern is predicated on the spinning disk becoming the bottleneck of our system. In the future, this pattern will become less useful as other forces come to dominate our system architecture. Two of the control flow patterns, Observer and Strategy, are held in common with the GoF catalog, though in the context of functional programming a few new variations become more obvious. It also seemed to me that Sierra's Wrapper is a lot like the GoF's Decorator, though he did not make an explicit connection. As I wrote a couple of years ago, the time is right for functional design patterns. I'm so glad that Sierra has been documented patterns of this sort and articulating the value of thinking in terms of patterns. The key is not to look to OO programs for patterns of value to functional programmers, but to look at functional programs for recurring choices among design alternatives. (It's not too surprising that many OO design patterns don't mean much to functional programmers, just as it's not surprising that FP patterns dealing with, say, state are afterthoughts in the OO world.) I look forward to reviewing Sierra's slides, available at StrangeLoop 2012 GitHub repo, and coming back to the topic of functional design patterns soon. The first day of StrangeLoop was off to a great start. -----