YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
Talks are the traditional format and are 30 minutes long;
Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
If you’re still not convinced, check out the program.
The conference will run for 2 days, May 16-17, in Brisbane. Tickets are on sale.
Clojure
Besides the conference itself, Clojure/core will be giving an Intro to Clojure workshop in Sydney, Melbourne and Brisbane. It’s a great opportunity to learn from the language maintainers.
If you’re attending the conference already, you’re in luck because there is a 20% off discount on the link above if you attend both the conference and the workshop.
In case you’d like to attend the workshops only, you can buy individual tickets for Sydney, Melbourne and Brisbane.
Scala
Tony Morris will also be delivering a Functional Programming in Scala workshop in Brisbane and 20% off combo tickets can be bought from the EventBrite page for LambdaJam.
If you haven’t read SICP, you should. It’s an amazing book. It uses Scheme, a dialect of Lisp, as the vehicle to present fundamental programming concepts.
Philip Wadler - the author of this particular paper - contrasts teaching in Scheme to teaching using KRC and Miranda, pointing out
four major features he considers important and lacking in Scheme. They are:
Pattern matching
A syntax close to traditional mathematical notation
A static type discipline and user-defined types
Lazy Evaluation
Note: KRC influenced Miranda which in turn influenced Haskell. Their syntax is similiar, so where Wadler used Miranda code snippets in the paper, I’ll be using Haskell in this post.
As an aside, although the paper talks specifically of Scheme, the term Lisp is used quite loosely and could lead the not-so-careful reader to be misled regarding a whole family of languages. Lisps have come a long way and modern dialects - of which I’ll be focusing on Clojure - address many of the concerns raised by Wadler.
Let us begin.
Pattern Matching
Here Clojure, and most - all? - Lisps, are out of luck.
The example used in the paper is that of summing all integers in a list. First in Haskell:
The question here is this: Which snippet is easier to read/reason about? the Haskell code!
I must confess that I, too, miss pattern matching sometimes. However we can still improve our Clojure version to read nicer on the eyes by using destructuring:
And that’s pretty much it. Without proper pattern matching, we can’t get much better than that.
In addition to the Haskell snippet being easier to read, it’s also easier to prove correct by structural induction, as demonstrated in Wadler’s paper.
Note: core.match adds support to pattern matching in Clojure. At the time of this writing, it’s considered “alpha quality”
Data structures
The paper continues to discuss exercise 2-27 from the SICP, where the reader has to write code to represent a binary mobile, which consists of a left and right branch with each branch being a rod of certain length, from which hangs either a weight or another binary mobile.
Translating the Scheme example to Clojure, such a structure is represented using lists, like so:
Granted, it’s still not as clear and the compiler can’t validate the shape of our data structure.
This is however cleaner than the previous version and drives home the point that Clojure isn’t limited to lists, having literals for other data types such as the hash maps used in this example.
The second part of this claim is that through custom data types and pattern mathing, extracting values from those structures becomes simpler:
For a language with no pattern matching nor algebraic data types, this snippet is clear, concise and elegant - and a real improvement
over the Scheme version discussed in the paper - which was essentially handicapped by the use of lists to simulate ‘structs’.
As far as Clojure goes, this claim ends here: the next point in the paper, about changing from using list to using cons, is rendered moot since
we’re using hash maps to represent our mobiles.
Both statements above are equivalent, with the second one being clearly more concise.
The claim here is that the fact that you need to either use the list function or quote the form is cumbersome and can be confusing to beginners.
Clojure solves this by providing literals to another data structure - vectors:
1
[[12]nil]
Simple and concise - in fact, in idiomatic Clojure code, you’ll rarely see quoted lists where a vector will do.
This is possible because both lists and vectors conform to a higher level abstraction called a Seq, in terms of which most list
operations are defined.
This eliminates the two following points mentioned in the paper as it allows a beginner to defer his/her understanding of quoted forms
to more advanced lessons/usages.
Programs that Manipulate Programs - the interpreter example
Here Wadler shows a simple grammar for an interpreter in both Miranda and Scheme.
He claims that since Haskell/Miranda have free data types, representing such grammar becomes simpler:
The strength in Lisp lies elsewhere. Since we have quoted forms, entering a similar term is a lot less verbose and closer to its intended representation:
1
'((lambda[x](xx))(lambda[x](xx)))
This is, of course, at the expense of making eval a more complicated function:
The paper leaves out an important advantage of Lisps though:
Because we can write code for our made up language directly in its (almost)abstract syntax tree form, Lisps are the ideal choice when writing Internal Domain Specific Languages.
Lazy Evaluation
Lists
Haskell and Miranda are lazy languages and that yields a lot of power. This claim is more specific to the use of lazy lists - or sequences, streams - and starts off with a snippet that calculates the sum of squares of all odd numbers from 1 up to 100:
1
sum[i*i|i<-[1..100],oddi]
What follows in the paper is a not-so-clear snippet of equivalent functionality using Scheme streams.
Clojure features lazy sequences and list comprehensions, making the above Haskell example trivial to write:
1
(sum(for [i(range 100):when(odd?i)](* ii)))
If you’re following at home with the original paper you’ll see this is more readable and elegant than the equivalent Scheme example.
Another - also idiomatic - way to write the same expression is by using a combination of map/filter:
1
(sum(map #(*%%)(filter odd?(range 100))))
Deciding which one is clearer is left as an exercise to the reader.
Special forms and lazy evaluation
In this section, Wadler brings another example from SICP where the reader wishes to implement his/her own if form.
As we know, in order to implement our own version of if, we need to use macros. That is because in Lisps arguments to functions are eagerly evaluated.
In Lazy languages, such as Haskell and Miranda, this problem doesn’t occur allowing such functions to be defined without the need for special and/or quoted forms:
12
myIfTruete=tmyIfFalsete=e
However this completely dismisses the power of macros which allow you to extend the language in ways no other language allows - as is extensively demonstrated in books such as On Lisp and Let Over Lambda.
As Guy Steele once put it: ”[…] If you give someone Lisp, he has any language he pleases”
Conclusion
Hopefully this post doesn’t come off as trying to invalidate Wadler’s paper - that is not my intention.
While I do think a few of the points discussed are only applicable to the domain in which his paper was written - teaching - they are still valid and worth understanding.
I do however expect to have given you a different perspective on it, showing the strengths of modern Lisps such as Clojure and how it approaches these issues - such as by using its rich set of data structures, literals and techniques such as destructuring.
Last year I started reading a book called Purely Functional Data Structures. It’s a fascinating book and if you’ve ever wondered how Clojure’s persistent data structures work, it’s mandatory reading.
However, all code samples in the book are written in ML - with Haskell versions in the end of the book. This means I got stuck in Chapter 3, where the ML snippets start.
I had no clue about Haskell’s - much less ML’s! - syntax and I was finding it very difficult to follow along. What I did notice is that their syntaxes are not so different from each other.
So I put the book down and read Learn You a Haskell For Great Good! with the hopes that learning more about haskell’s syntax - in particular, learning how to read its type signatures - would help me get going with Puretly Functional Data Structures.
Luckily, I was right - and I recommend you do the same if you’re not familiar with either of those languages. Learn You a Haskell For Great Good! is a great book and I got a lot out of it. My series on Monads is a product of reading it.
Enough background though.
The purpose of this post is two-fold: One is to share the github repository I created and that will contain the Clojure versions of the data structures in the book as well as most solutions to the exercises - or at least as many as my time-poor life allows me to implement.
The other is to walk you through some of the code and get a discussion going. Hopefully we will all learn something - as I certainly have when implementing these. Today, we’ll start with Leftist Heaps.
Leftist Heaps
Leftist Heaps - or trees - are a variant of binary heaps that can be used as priority queues. On top of the standard invariants of binary heaps, it obeys the leftist property:
Every node has a rank, which is the distance from its right spine to the nearest leaf
A node’s left child has a rank at least as large as its right child
In a nutshell, these are the operations we need to be able to perform on a leftist heap:
insert a value into an existing heap
merge two heaps
find the minimum value in a heap
delete the minimum value, returning a new heap
Since the book uses ML/Haskell, it starts with a data type definition for Heaps that exposes these and a couple of other auxiliary functions. I decided to take a stab at writing the solution using Clojure’s protocols and records:
When implementing the algorithms the base case for the recursive solutions will involve dealing with nil values which at first seems like it wouldn’t be a problem. However, protocol functions dispatch on the type of its first argument so what happens if I call the function is-empty? on nil?
Luckily, Clojure allows us to extend a protocol to core types:
The reason this function is isolated is that the Heap protocol defined above is fairly generic and could be used for defining other types of heaps - and I didn’t feel it warranted its own interface.
We can now play with it and create a new leftist heap:
While I quite like this approach, I thought I’d also implement this solution using Clojure’s core data types - maps in this case - and no protocols. The code is shown below:
If you’d like to see more examples and a detailed guide check out the github repository. The README should get you started.
This post however isn’t only about announcing bouncer. It’s also about the motivation and implementation details behind it.
There are a couple of Clojure validation libraries already out there so why would I write a new one?
Well…
Writing Clojure is fun! (who knew? :P)
Because I believe this problem can be solved more elegantly with the use of Monads
If you’ve been following me for a while, you’ll know that I spent most of 2012 deepening my knowledge about functional programming.
In that journey, the unavoidable subject of monads came about - and it was both interesting and enlightening enough that made me write a whole series of posts about it.
After learning what they are and then thinking about the validation problem for a while, I couldn’t help but notice that the problem had a lot in common with the State Monad.
In order to explain how the two relate, I’ll have to digress for a moment. It’ll all make sense in the end - or so I hope
Purity
In pure functional languages, such as Haskell, functions can’t have side effects. These include performing IO, changing global variables or launching missiles.
Because of that, functions in Haskell are pure: if you repeatedly call a function f with the same argument x over time you will always get the same result back.
Pure functions are not a feature of Haskell though. We, too, can write pure functions if we wish:
12
(defn double[x](+ xx))
The function double above is pure. If we call it with 10, we can be sure the result will always be 20.
This leaves us with a question though: If we were to write our programs with pure functions only, how would we perform computations that need to carry state - state that needs to change over time - around?
A good example of such computation is generating random numbers.
Most programming languages provide generators capable of creating random numbers on demand. Using them is usually trivial. Here’s an example in Java:
The function nextDouble above is obviously not pure. Multiple invocations of it with the same argument - in this case, none - returns different results.
nextDouble is keeping some sort of global state between function calls.
This is where the State Monad comes in. It allows such functions to remain pure.
The State Monad
The State Monad provides a way to abstract state from the function that needs to operate on it.
Sounds confusing? Hopefully an example will clear things up.
rand suffers from the same problem as nextDouble we saw above. It keeps it’s own state that is shared across calls, therefore being an impure function.
Now let’s write a pure version of rand. We’ll call it pure-rand:
This is interesting. pure-rand now takes a generator as an argument and returns a two-element vector containing the random number itself - the result we’re actually interested in - and the generator that was passed in.
Recall however that the generator returned, albeit the same object, is in a new sate.
By re-writing the function like this, we’ve regained purity, as demonstrated below:
As you can see, as long as we provide the same generator - the same argument - we get the same result back.
If you’re wondering why I’m returning a two element vector from our little function, the answer lies in the State Monad implementation as found in the algo.monads library.
From its docstring:
State Monad: Monad describing stateful computations. The monadic values have the structure:
(fn [old-state] [result new-state]).
It expects a function that receives its old state and returns the result and the new state - these are called monadic values.
By designing the function to follow this contract, we can leverage the domonad macro - think of it as syntactic sugar for working with monads:
In the example above, we’re using our pure-rand function in the context of the State Monad to generate 3 random numbers - based on some initial state - and returning them as a vector.
As we’ve seen before the result is itself in a vector alongside the new state.
This is where the State Monad and the validation problem meet:
In bouncer, each validation function is designed to be compatible with the State Monad, just like pure-rand above:
It receives an initial state - at first, the map to be validated - and returns a vector with the map of errors and the new state: the original map augmented with any errors from previous validators.
The end result, should one or more validations fail, is a map with all errors that might have happened, plus our new state.
Now if you head to the github repository and read the examples by keeping the State Monad and the above explanation in mind, the similarities should be obvious.
Wrapping up
As I mentioned in the beginning of the article, there are other validation libraries for Clojure and at the time of this writing they have more features than bouncer - by all means have a look at them.
However I will keep maintaining bouncer for a couple of reasons:
That’s what I’m using in my current side project
It takes a fundamentally different implementation approach that is in itself worthy of exploration
If nothing else, this is yet another example of where Monads can be useful.
Acknowledgments
Thanks to Steve and Julian for reviewing early drafts of this post as well as Nick for being such a PITA :) - our discussions led to a considerably nicer design.
Keeping the tradition of end-of-year blog posts, here are my year highlights for 2012:
Clojure
I started clj-syd - the Sydney Clojure User Group - back in January and it has seen a major uptake. We consistently get an average of 25 people each month and there’s no shortage of talks and topics to discuss. It’s a great crowd and I’m proud to have started it and of being part of it.
Speaking
I spent most of the year studying functional programming and I tried to make my talks reflect that. Even the javascript talk I gave in April had a FP focus. Anyway, you can find some of the slides online:
Clojure Reducers - Another preso I gave at the clojure user group, in August.
Books
As usual I read a number of books this year and these are my favourites:
The Little Schemer
As they say, an oldie but a goodie. This is mandatory reading for anyone who consider themselves a serious programmer. The insights and techniques found here are invaluable. Do yourself a favor and buy it now.
This is pretty much how I learned Clojure. I actually started reading it in November 2011 but felt I needed to put it down from time to time to go and code on my own to solidify what I learned. That’s why I only finished it in 2012.
This book packs a great deal of info and is a great way to get into both functional programming and Clojure.
Learn you a Haskell for Great Good
This is the best intro to Haskell ever. Hands down. ‘nuff said.
Clojure Programming
I like reading different books about the same subject to get to see it from various perspectives. Clojure Programming takes a different approach to The Joy of Clojure in that, as it progresses through topics and code examples, it contrasts it with languages likely to be familiar to the reader, such as Java, Ruby and Python. Another great alternative if you’ve been thinking of getting into Clojure but didn’t know where to start.
Content
Here’s just a few of the posts visitors found most interesting this year:
Monads in Small Bites Parts I, II, III & IV - Even though I only published this series in December, it quickly became one of the most read posts that month. And it’s also a personal favorite.
Build Automation With XCode 4.3, KIF and Jenkins - This turned out to be very popular - build automation and testing are not among the top priorities within the iOS community so I’m glad this helped some people out. It’s getting way better now.
JRuby on Rails and Legacy Java Apps: Managing Dependencies - The JRuby enterprise world seems to be hotter than ever before. I wouldn’t think this post from 2009 would still get this many visits. I haven’t been involved much with JRuby as of late so I wonder if this is still the way to go?
LambdaJam
LambdaJam is a conference for functional programmers and although it’s set to happen in May 2013 the wheels have already started turning - thus I had to list it as a highlight.
I’m fortunate enough to be involved with the organization alongside very bright people from the Australian functional programming community as well as Dave Thomas from the YOW! Conference who’s leading the effort. We’re all really excited about it.
Stay tuned, lots more info to come!
Goals
No resolutions. Goals. And I wanna achieve them. They’re simple and I hope this post will keep me in check
Better utilize my free time
This is a bit abstract but will help me achieve the goals below. The output of this goal is a calendar with time slots assigned to each one of the next goals - I’ve just done this now actually so this is a good start. No more procrastinating.
Books
I got a big pile of books I wanted to have read in 2012 so I’ll be updating my good reads profile with them and make sure I just do it - with the help of my new calendar from the goal above.
Side projects
In 2012 I worked on two side project which are not ready yet, so I can’t comment a whole lot on them apart from saying that one is being developed in Clojure and the other in Ruby - in 2013, these two will see the light of day.
Here’s to a new year
I hope you all had a great 2012 and are as excited as I am for the new year.
Happy holidays, safe driving and awesome parties! :)
In Part I we learned about Functors, which are things that can be mapped over using a normal function - fmap is used for that.
Part II tought us that when our Functors themselves contain functions and we want them applied to the values contained in other Functors, Applicatives come to the rescue - and bring theirs friends pure and <*>.
Part III introduced Monoids which model a special type of relationship involving binary functions and their identity values.
Now it’s time for what I hope is the post you have all been waiting for :)
Monads
A word on context
So far I’ve said things such as wrapping stuff in Functors, unwrapping functions from Applicatives and putting results into minimal Functors. All this really means is that [Applicative]Functors - and Monads - have associated contexts that model some sort of computation.
For lists, for example, this means they represent computations that can have several results - non-determinism.
These computations can have much greater implications though - they can represent failure (or not!), do IO and even launch nuclear missiles. The point is: when we combine Functors/Applicatives/Monads, we carry their context with us to the end - they are essentially sequenced together.
This will become clearer with an example. For once I won’t start with lists - w00t! - so get ready for it!
The Maybe Monad
The Maybe monad models computations that can fail. Let’s have a look at an example.
Say you have an e-commerce system. When placing an order, a few things need to get done:
gather information about the order;
calculate shipping rates;
apply discount codes, if any, and;
finally place the order.
The code below shows the supporting functions that will be orchestrated in order to achieve this:
Note that based on the code above, we can only ship to Australia and there is only one active discount code. Keep this in mind - you’ll see why later on.
Now let’s place an order for some Jalapeño sauce:
123456789101112131415
(def order{:items[{:name"Jalapeño sauce":price20.0}]:address{:country"Australia"}:discount-code"XMAS2012":total20.0})(def shipping-rate(calculate-shipping-rate(:addressorder)))(def discount(lookup-discount-code(:discount-codeorder)))(-> order(apply-shipping-costsshipping-rate)(apply-discount-codediscount)(place));; "Off you go! Order total: $25.0"
Great! Soon I’ll be receiving some hot sauce to go with my burritos!
But wait, what if I had mistakenly set my address to somewhere other than Australia? How would this code behave?
Oops! Your e-commerce system just crashed! Not cool. But hey, this is easy to fix, right? We could just change our apply-shipping-costs function to something like this:
12345678910111213
(defn apply-shipping-costs[ordershipping-rate](if shipping-rate(assoc order:total(+ (:totalorder)shipping-rate))order));;Remember we only support one discount code so the same problem could happen again;;We need to change the apply-discount-code function as well(defn apply-discount-code[orderdiscount](if discount(assoc order:total(- (:totalorder)discount))order))
Now let’s see what happens:
12345678
(def shipping-rate(calculate-shipping-rate(:addressanother-order)))(def discount(lookup-discount-code(:discount-codeanother-order)))(-> another-order(apply-shipping-costsshipping-rate)(apply-discount-codediscount)(place));; "Off you go! Order total: $15.0"
Well, it doesn’t crash but we can’t ship to Brazil anyway! So the code is still incorrect! What we really want is a way to halt the whole computation - placing an order - if any of those steps fail.
Of course we could fix it with a couple more if forms before trying to call the place function but you see where this is going.
Essentially our nice little functions became burdened with context: each of them is now aware that they can fail and need to cater for it.
Enter the Monad
I’ll jump straight to how the code could look like if we had monads - it won’t work now because we haven’t actually implemented the monad yet, but this should whet your appetite.
Also, assume we reversed the changes from before - the functions don’t have the if forms checking its arguments any longer, just like in the original version. Here’s the code:
12345678910111213141516171819
(domonadmaybe-monad[orderordershipping-rate(calculate-shipping-rate(:addressorder))discount(lookup-discount-code(:discount-codeorder))](-> order(apply-shipping-costsshipping-rate)(apply-discount-codediscount)(place)));;"Off you go! Order total: $25.0"(domonadmaybe-monad[orderanother-ordershipping-rate(calculate-shipping-rate(:addressorder))discount(lookup-discount-code(:discount-codeorder))](-> order(apply-shipping-costsshipping-rate)(apply-discount-codediscount)(place)));; nil
domonad receives the monad you want to operate on, a vector of bindings and an expression that’s the final result of the whole thing.
Is your mind blown yet? :) Somehow the whole operation fails and yields nil in the second call to domonad above - without any if forms and without crashing! To see why that is, I’ll now explain the monad type class from Haskell.
The Monad Type Class
Here’s the Haskell definition of the Monad type class (I left the fail function out so we can focus on the core of it):
return - much like pure from Applicative Functors, return is responsible for wrapping a value of type a into a minimum context Monad that yields a value of type a - referred to as a monadic value.
(>>=) - often called bind - is a function of two arguments. The first is a monadic value of type a and the second is a function that receives a value of type a and returns a monadic value of type m b which is also the overall result of the function.
In other words: bindruns the monad m a, feeding the yielded a value into the function it received as an argument - any context carried by that monad will be taken into account.
(>>) - often called then - This function receives two monads, m a and m b, and returns a monad of type m b. It is generally used when you’re interested in the side effects - the context - carried out by the monad m a but doesn’t care about the value a it yields. It’s rarely implemented in specific monads because the type class provides a default implementation:
It applies bind to the monad x and a function that ignores its argument (\_ -> y) - which by convention is represented by an underscore - and simply yields the monad y: that’s the final result of the computation.
I won’t be implementing then in Clojure though - I’ll focus on return and bind, since then is essentially a helper function you could write yourself.
The Maybe Monad - Clojure edition
With definitions out of the way, let’s implement the Clojure version of the Maybe monad.
For the maybe monad, all its context needs to represent is a single value or the absence of value. We do this inside bind by checking if the monadic value mv is nil. If it isn’t, we apply f to it, which will yield another monadic value. If, on the other hand, mv IS nil, we just return nil, bypassing the function application entirely.
return, as we saw, wraps a value into a minimal monad. In this case this is the value itself, so we just return it untouched.
WOW! That is awful! And I won’t blame you for not wanting to read through this aberration. But trust me, it does the job.
However, you’re probably thinking: that looks nothing like the nice little domonad notation we saw earlier!
Well, you’re right. That’s because domonad is a macro - it gives us some syntactic sugar that expands into the real code shown above. In order to be able to use the domonad notation, paste the following into your REPL:
Note: macros can be daunting at times so don’t worry too much about its implementation. It’s way more important to me that you understand the end result than it is to be able to implement the macro yourself - but by all means dissect this implementation if you feel inclined to do so :)
Now that’s way better. The maybe monad abstracted away the logic behind computations that can fail so you don’t have to worry about it in your functions - you can just focus on writing them.
In the end I also believe it aids readability once you get used to it.
Don’t break the law
Monads have laws of their own too! Let’s have a look at them.
Right unit
Binding a monadic value m to return should be equal to m itself
In Haskell speak:
1
m>>=return=m
The proof in Clojure:
123456789
(def m10)(def >>=(:bindmaybe-monad))(def return(:returnmaybe-monad));; given the above, this...(>>=mreturn);; 10;;is the same asm;; 10
Left unit
Applying return to x and then applying >>= to the resulting value and fshould be the same as applying f directly to x
In Haskell speak:
1
returnx>>=f=fx
The proof in Clojure:
12345678910
(def x10)(def >>=(:bindmaybe-monad))(def return(:returnmaybe-monad))(def f(fn [v](* v2)));; given the above, this...(-> (returnx)(>>=f));; 20;;is the same as(fx);; 20
Associativity
Binding m to f and then applying >>= to the result and g should be the same as applying >>= to m and a function of argument x that first applies f to x and then binds it to g.
Phew…another mouthful, huh? Code should make it clearer. As usual, Haskell comes first:
1
(m>>=f)>>=g=m>>=(\x->fx>>=g)
And now let’s prove it in Clojure:
1234567891011121314
(def >>=(:bindmaybe-monad))(def return(:returnmaybe-monad))(def m10)(def f(fn [v](* v2)))(def g(fn [v](+ v10)));; given the above, this...(-> (>>=mf)(>>=g));; 30;;is the same as(>>=m(fn [x](>>=(fx)g)));; 30
Alright, we’re getting to the end now! Hold on just a little longer!
One last thing - The List Monad
Yeah, I’m sure you saw this coming. Lists are monads too! I’ll make this quick and show its implementation and usage in Clojure - bear with me one last time.
123456789101112131415161718192021
(def list-monad{:return(fn [v][v]):bind(fn [mvf](if (seq mv)(apply concat(map fmv))[]))});;let's play with it(domonadlist-monad[a[12]b[a,(- a)]](* 3b));; (3 -3 6 -6)(domonadlist-monad[a[12]b[]](* 3b));; () - an empty list.
This should look familiar if you’ve used list comprehensions in Clojure or other languages such as Python:
1234
(for [a[12]b[a,(- a)]](* 3b));; (3 -3 6 -6)
See? You’ve been using monads all along and didn’t even know it! How awesome is that?
Also note that we didn’t need to re-implement domonad for the list monad. It’s a generic macro that will work with any monads you throw at it!
It’s interesting to see how the list and the maybe monads differ. This time, return puts the value v inside a list and returns it because for lists, a minimum monad is a list with a single element.
bind is a bit more interesting. It first checks to see if mv is empty, in which case it returns an empty list, causing the whole computation to stop. If, however, mv is NOT empty, it maps f over every element in mv.
The resulting list is potentially a list of lists, since functions fed to monads - such as f in this case - have to return monadic values. That’s why we then apply concat to the resulting list, effectively flattening it.
Final words
Hopefully you now have a much better understanding of Monads and should start seeing in your code use cases and/or opportunities for the monads shown here.
You’ll notice that this Clojure implementation of monads used only normal functions - that was by design since I wanted this implementation to be as close as possible to Clojure’s core.algo.monads library. You should have a look at it.
Also, bear in mind that this tutorial is by no means exhaustive - there’s a lot more about monads that I could possibly cover in a blog - it was hard enough ending it here! But if you want to study more about them, I’d recommend starting with these resources:
Learn You a Haskell for Great Good - this book is an excellent intro to Haskell and it was the approach found there that made me grok monads - highly recommended and freely available online.
This type introduces three new functions so let’s walk through each one of them:
mempty - I started with a lie since mempty isn’t actually a function. You can think of it as a constant of the same type of the Monoid m. It is this monoid’s identity value.
mappend - A poorly named function, mappend is the binary function I mentioned earlier. It receives two arguments of type m and returns a value of type m
mconcat - It receives a list of Monoids m and reduces them to a single Monoid of type m. What’s interesting about this snippet is that the Monoid type class provides a default implementation for mconcat: it simply calls foldr with the binary function mappend, a starting value of mempty and the list of Monoid values ms
Enough Haskell! Let’s have a look at a few examples.
Did you know that, in Clojure, the functions * and + are monoids? Yup. But don’t take my word for it. Let me prove it to you:
Whoa! What happened here? Am I just making this stuff up?
Not really. I only defined the same haskell names to their Clojure counterparts for clarity. Totally overkill. The code above is the same as:
12345
(+);; 0(+ 34);; 7(reduce +[234]);; 9
Did you notice that on the second call to reduce we did not provide an initial value? That’s because reduce will attempt to get its initial accumulator by calling the reducing function without arguments - hence mempty == (+).
So that means we don’t even need an mconcat function since in Clojure, reduce works with monoids as well!
Update: this isn’t entirely true. When I wrote this post I had in mind the version of reduce provided by the Clojure (1.5+) reducers library. The source code shows how that is the case.
The implementation of reduce in clojure.core however uses the first element of the collection being reduced over as its seed.
But how the hell do you create a monoid in Clojure then? I’m glad you asked. Let’s create our own plus-monoid!
This time around I won’t be using any of these. I’ll implement Monoids using pure functions:
1234567891011
(defn plus-monoid([]0)([ab](+ ab)))(plus-monoid);; 0 - same as mempty(plus-monoid34);; 7 - same as mappend(reduce plus-monoid[234]);; 9 - when working with monoids, reduce is the same as mconcat
We start by defining a function with multiple arities. The first body receives no arguments, so we just return the identity value for summation, which is 0 (zero). The second body receives two arguments so we can just add them up. Multiplication can be implemented in a similar fashion but obviously with the identity value of one.
Easy, huh?
Oh, by the way, lists are Monoids too! Who’d have thought?
Here’s its Clojure implementation:
1234567891011
(defn list-monoid([]'())([ab](concat ab)))(list-monoid);; () - remember, same as mempty(list-monoid[123][456]);; (1 2 3 4 5 6) - remember, same as mappend(reduce list-monoid[[123][456][789]]);; (1 2 3 4 5 6 7 8 9) - mconcat in action
Same rules apply but for lists mappend is achieved by using concat inside our monoid function.
Also, since our binary function concatenates two lists together it makes sense that mempty is () (the empty list). Remember mempty is supposed to be an identity value so if we stitch () and [1 2 3] together, we’re left with [1 2 3] which is exactly what we’d expect.
You can see now why I said mappend was poorly named. While it makes sense when you think about lists, mappend doesn’t do any appending in our plus-monoid and in fact most monoids don’t append anything. Just keep this in mind if you see any haskell code using it: mappend is just a binary function.
Don’t break the law
You saw this coming, huh? Monoids also come with a couple of laws. You know the drill. Let’s prove they both hold.
Identity
Applying mappend to mempty and a monoid x should be the same as the original x monoid.
In Haskell:
12
mappendmemptyx=xmappendxmempty=x
And the proof in Clojure:
123456789101112131415161718192021
;; first, the plus-monoid(def mempty(plus-monoid))(def x10);; This...(plus-monoidmemptyx);; 10;; ...is the same as:(plus-monoidxmempty);; 10;;now, the list-monoid(def mempty(list-monoid))(def x[123]);; This...(list-monoidmemptyx);; (1 2 3);; ...is the same as:(list-monoidxmempty);; (1 2 3)
Associativity
Applying mappend to a monoid x and the result of applying mappend to the monoids y and z should be the same as first applying mappend to the monoids x and y and then applying mappend to the resulting monoid and the monoid z
In Haskell:
1
mappendx(mappendyz)=mappend(mappendxy)z
And the proof in Clojure - remember that calling the monoid function with two arguments is equivalent to mappend in haskell:
1234567891011121314151617181920212223
;; first, the plus-monoid(def x10)(def y25)(def z40);; This...(plus-monoidx(plus-monoidyz));; 75;; ...is the same as:(plus-monoid(plus-monoidxy)z);; 75;;now, the list-monoid(def x[40])(def y[1025])(def z[50]);; This...(list-monoidx(list-monoidyz));; (40 10 25 50);; ...is the same as:(list-monoid(list-monoidxy)z);; (40 10 25 50)
Almost there…
This puts an end to Part III. It’s time to head to the pub.
When you’re back look for the final post in these series - Part IV - where we will conclude our journey by finally introducing Monads!
In Part I I talked a little about Haskell type signatures and introduced Functors, which provide a way to map standard functions over values which are wrapped inside a Functor - we used fmap for that. You might want to skim through it again as a refresher.
Now suppose you have Functors that wrap functions and that you want to apply those wrapped functions to other Functors, maybe even composing new functions on the way!
What then?
Well you’re in luck! Applicative Functors do just that! They’re Functors on steroids.
Here’s how Haskell defines the Applicative data type:
Based on our previous knowledge of Haskell’s type signatures, we can infer from this definition that in order for it to be an Applicative Functor, fmust already be a Functor.
Let’s break this down and have a closer look at the two new functions this type introduces:
pure is a function that takes a value a and wraps it into a minimal Functor f.
<*> is a function that takes two arguments: the first is a Functor f that wraps a function of type a -> b. The second argument is a Functor f that wraps a value - which could be a function! - of type a. The final result is a Functor f that wraps some value of type b - which was obtained by somehow applying the function (a -> b) to the Functor f a.
pure has a straightforward explanation whereas <*> is a bit more involved.
To clear things up, I’ll show the type signatures again but this time as if they only worked with the List Functor that we’ve been working on:
12
pure::a->[a](<*>)::[(a->b)]->[a]->[b]
Let’s revisit those definitions:
pure is a function that takes a value a and puts it into an empty list, returning the resulting single element list.
<*> is a function that takes two arguments: the first is a list containing one or more functions of type a -> b. The second argument is a list of one or more values - or functions! - of type a. The final result is a list of one or more values of type b - which was obtained by somehow applying the function (a -> b) to the Functor f a.
Enough definitions though! Let’s extend our List Functor and make it an Applicative as well.
While we’ll still be using the List Functor we implemented in Part I, this time I’ll implement its Applicative version using multimethods for a change. Here’s the code:
12345678910111213
;; it dispatches on the record type since we could have implementations of pure for List, Maybe, Either etc...(defmulti pure(fn [f_]f))(defmethod pureList[_v]"Wraps value v in a list"(List.[v]));; it dispatches on the class of the Functor instance passed in the 1st argument(defmulti <*>(fn [fs_](class fs)))(defmethod <*>List[fsxs]"Unwraps the functions in fs, applies them to the Functors in xs, wrapping the result at the end"(List.(for [f(:wrappedfs)x(:wrappedxs)](fx))))
By focusing on the List as an Applicative Functor we can more easily understand what these functions do. From the code above, pure’s job is a simple one: all it does is wrap it’s argument v into a minimal List functor which in our case means a Functor wrapping a one element list.
<*> on the other hand is responsible for somehow unwrapping the functions brought in by the Applicatives in fs and applying them to the [Applicative] Functors in xs. It does that by using list comprehensions and wraps the result into a new List Functor.
Study this code carefully. It can be tricky.
Note: When I first encountered <*> I had no idea what this function was called. I asked the twittersphere and it seems it’s called apply. In the process of figuring this out I was enlightened by this conversation. It turns out <*> has several names. Can you guess which one is my favorite? :)
With the Applicative functions defined for our List, let’s take it for a spin:
There should have been no surprises here. Read the code again and make sure it’s all fresh before moving along.
Don’t break the law
Just as Functors, Applicative Functors also need to obey some laws:
Identity
Feeding a function f to pure and applying the resulting Applicative to the Functor v should be the same as directly mapping f over the Functor v
In Haskell speak:
1
puref<*>v=fmapfv
And this is the proof, in Clojure:
123456789
(def f#(+2%))(def v(List.[10]));; given the above, this...(<*>(pureListf)v);; List{:wrapped (12)};; ...is the same as:(fmapvf);; List{:wrapped (12)}
Composition
The result of applying an Applicative Functor that yields the function composition operator to the Applicative u, then apply the resulting Functor to v and finally applying that result to the final Applicative w should be the same as applyingv to w and then applyingu to the resulting Applicative.
That was a mouthful! Let’s see how Haskell tells this story:
In Haskell:
1
pure(.)<*>u<*>v<*>w=u<*>(v<*>w)
I needed to cheat a bit in Clojure to prove this law since functions are not curried by default like they are in Haskell. But this code should still clearly show how this law holds:
123456789101112
(def u(List.[#(*2%)]))(def v(List.[#(+10%)]))(def w(List.[123]));; Given the above, this...(-> (pureList(fn [x](partial compx)))(<*>u)(<*>v)(<*>w));; List{:wrapped (22 24 26)};; ...is the same as:(<*>u(<*>vw));; List{:wrapped (22 24 26)}
Homomorphism
The result of applying the pure value of f to the pure value of x should be the same as applying f directly to x and then feeding that into pure.
In Haskell:
1
puref<*>purex=pure(fx)
And in Clojure:
123456789
(def f#(*2%))(def x10);; given the above, this...(-> (pureListf)(<*>(pureListx)));; List{:wrapped (20)};; ...is the same as:(pureList(fx));; List{:wrapped (20)}
Interchange
The result of applying an Applicative Functor u to the pure value of y should be the same as taking the Applicative obtained by calling pure with a function that applies its argument to y and then applying that to u
In Haskell:
1
u<*>purey=pure($y)<*>u
This type signature presents new syntax so before proving the law in Clojure, I want to explain what ($ y) means.
In Haskell, $ is the function application operator. So if we give y a value of 10, I can show you that in this law $ essentially translates to a single argument function that applies its argument to 10:
12345678
letdoublea=a*2-- helper function. it doubles its argument-- given the above, this...(($10)double)-- 20-- ...is the same as:letdollarTen=(\a->(a10))-- this is Haskell's lambda syntax. It's equivalent to ($ 10)((dollarTen)double)-- 20
Now, to the proof in Clojure:
123456789
(def u(pureList#(+10%)))(def y50);; given the above, this...(<*>u(pureListy));; List{:wrapped (60)};; ...is the same as:(def dollar-y#(%y));; it's called dollar-y to show the correlation with the explanation above(<*>(pureListdollar-y)u);; List{:wrapped (60)}
This brings us to the end or Part II. Two down and two to go.
I hope you’re still with me but go home now.
Or better yet go to the gym lift some weights and think about these Functors on steroids. When you’re back, look out for Part III.
Today I join the already bloated group of people who wrote monad tutorials. It’s a bit of a ritual, really.
Different than most tutorials though I aim to take a different approach. The good news is that I won’t be comparing monads to burritos :)
People say one needs to have his/her own epiphany in order to understand Monads and reading explanations from others is of little help. My goal is to disprove that.
To that end, this tutorial will be split in four parts:
You might want to bookmark this page - once the other parts are up, I’ll update the list above with the links to them.
Before we start
I know what you’re thinking: Do I really need to know Applicative Functors just to grasp Monads?
Well, no. However, I found that gradually building your knowledge from Parts I, II and III will allow you to fully grasp monads without the need for burritos or elephants.
You should also be familiar with a functional programming language. Any language should be fine but you’ll get the most out of this tutorial if you’re familiar with Haskell and/or Clojure.
If you’re not familiar with Clojure, fear not - Clojure is a small language and the code snippets should still make sense if you put your mind to it - they’re all short and sweet. I also encourage you to re-implement the examples in your language of choice to gain a deeper understanding on the subject.
Ready then? Let’s dive in.
Just enough Haskell
This is not a Haskell tutorial but trust me when I tell you that learning just enough about its type signatures will make all the difference in the world in understanding the concepts I’m about to present.
Although I’ll be using a little bit of Haskell syntax, I’ll also provide implementations in Clojure. They are in order so you should be able to paste all code sample in the REPL and follow along if you wish.
Type signatures
I’ll make this quick. Say you have a function called mk-vec that creates a 2D vector with x and y coordinates. Such function could easily be coded in Clojure like this:
123456
(defn mk-vec[xy]{:xx:yy});; using it(def my-vec(mk-vec1015))(:xmy-vec);; 10
As you can see, this function takes two arguments - x and y - and returns a map - or hash if you come from Ruby - that wraps those values in it, providing an easy way to retrieve them.
Now if this function had been implemented in haskell this would be its type signature - read the comments:
12345678910
importqualifiedData.MapasMap-- just giving Data.Map an aliasmkVec::a->a->Map.Map[Char]a-- this is the type signaturemkVecxy=Map.fromList[("x",x),("y",y)]-- this is the implementation. You can ignore this part.-- using itmyVec=mkVec1015Map.lookup"x"myVec-- Just 10 ---- ignore the actual value that is returned. Read it as 10 for now.
Whatever comes after the :: is part of the function type signature. Read it like this:
This is a function that receives two arguments of type a - which means any type - and returns a Map of key/value pairs where the key is of type [Char] - technically a list of Char values but for all effects and purposes just read it as String - and the value is of type a - the same type as its arguments.
It might help to see the type signature in this light:
1
mkVec::a->a->(Map.Map[Char]a)
It highlights the return value in parenthesis.
Now let’s have a look at a built in function, *. As you know, it performs multiplication and this is its type signature:
1
(*)::Numa=>a->a->a
Can you guess now what it means? I’m sure you can. There’s one small difference though: this function has a type constraint - it’s that Num a => … part of the signature. Read it like this:
This is a function that receives two arguments of type a and returns a value of the same type, as long as the type of a is an instance of Num
And that’s it for now. Read it again to make sure it’s fresh in your mind and then continue.
As we encounter more type signatures, I’ll walk you through each one of them - but if you got it up until now, you’ll easily grasp the other type signatures.
Functors
In a nutshell Functors are things that can be mapped over.
Haskell defines Functors like this:
12
classFunctorfwherefmap::(a->b)->fa->fb
Let’s dissect that type signature:
fmap is a function that receives two arguments: the first is a function that receives an argument of type a and returns a value of type b and the second is a Functor that contains a value of type a - represented by f a. The result of calling fmap is a Functor of same type - f - containing a value of type b, which is the result of applying the function to a.
Too much? Let’s have a look at an example: the List Functor.
If we rewrite the fmap type signature as if it only worked on lists, this is what we’d come up with:
1
fmap::(a->b)->[a]->[b]
This new type signature allows us to rewrite that last definition:
fmap is a function that receives two arguments: the first is a function that receives an argument of type a and returns a value of type b and the second is a List of zero or more values of type a. The result of calling fmap is a List of zero or more values of type b, each of which is the result of applying the function to each a element.
Does this sound familiar to you? It should, because this is essentially what the map function available in most functional-ish languages does! It takes a function and a list, applies the function to every element in the list while putting the results into a new list, finally returning it.
In fact, the fmap implementation of the List Functor from Haskell is implemented in terms of map.
Let’s see how that could be done in Clojure. I’ll use protocols and records but they are not strictly required for this.
Here’s our Functor protocol:
12
(defprotocolFunctor(fmap[functorf]"Maps fn over the functor f"))
In the snippet above all we’re saying is that the List record must satisfy the Functor protocol, which makes sense. fmap then is responsible for unwrapping the value contained in the list functor and mappingf over it.
We can now map arbitrary functions over the values wrapped in a Functor! Awesome!
Note: In our Clojure version of the List Functor, it is implemented as a Record that wraps a primitive Clojure list/vector - []. As I mentioned this is not necessary but I chose to do it here to explicitly show the relationship with the Haskell types.
Don’t break the law
Now that we got a feel for what Functors are, it’s worth noting that they must obey a few laws to be considered full-fledged Functors.
Identity
Mapping an identity function over a Functor is the same as applying identity to the Functor itself
This is how Haskell puts this law:
1
fmapidfunctor=idfunctor
Translating that to Clojure:
12345
;;This...(fmapmy-list-functoridentity);; List{:wrapped (1 2 3)};;is the same as:(identity my-list-functor);; List{:wrapped [1 2 3]}
Composition
If you compose the functions f and g and map the resulting function over the Functor, that is the same as first mapping g over the Functor and then mapping f over the resulting Functor.
From the description you can see that this law involves function composition. In Clojure, that’s achieved with the comp function.
Again, let’s see how this law is defined in Haskell:
1
fmap(f.g)functor=fmapf(fmapgfunctor)
Note: The . operator denotes function composition in Haskell
And the proof in Clojure:
12345678
(def f#(+10%))(def g#(*2%));; given the above, this...(fmapmy-list-functor(comp fg));; List{:wrapped (12 14 16)};; is the same as:(-> my-list-functor(fmapg)(fmapf));; List{:wrapped (12 14 16)}
A mobile app that could scan QR codes on a printed JIRA story card and provide features such as assigning a card to yourself, moving it between columns and adding comments to it.
This is a common need. Most people will manage their stories in some sort of software such as JIRA. But it’s also common to have a physical story wall.
The problem then is keeping them in sync. It’s all too common for people to move the cards on the well and forget all about JIRA.
Well, not anymore. This is exactly what our HackDay project tackles.
In 24 hours, we built two native mobile applications - Android and iPhone - that are able to scan QR Codes printed on the story cards and, through integrating with the JIRA REST API, provide all the necessary functionality needed for:
Assigning a story to yourself - whoever is logged in to the app
Moving the story between states - e.g.: In Analysis, Resolve Issue, Reopen Issue etc…
We didn’t stop there though. We actually finished early and had a couple of hours to spare so we shot a video - yes, a video!!! - about the app. I’m telling you, this is Hollywood quality:
Also, checkout some screenshots of the Android version: