 Hello, everyone. Thank you very much for choosing to give me your attention for 30 minutes of your finite lives. I'm going to try and tell you about monads and how we can uncover them by refactoring our Ruby code. Some of the ideas in this talk might be unfamiliar to some of you, so before we get stuck into the details, I'd like to warm our brains up with something simple. People always use analogies to explain monads. I don't think it really helps, so there'll be no burritos or spacesuits or elephants in this talk. Thank you. But I do want to talk about some related ideas, not analogies, but just related ideas that will put your brain into a receptive state for the stuff I actually want to say. I'm going to start our warm-up with a rhetorical question. What's a stack? Well, it's a kind of value with certain operations. Those operations are called push, pop, top, and empty. I'm talking about an immutable stack here, so push and pop don't mutate it, they just return a new one. You have to use top if you want to know what the top element is. We also need a class method called empty, which creates an empty stack to get us started. For a value to qualify as a stack, its operations have to follow certain rules. The rules just say that the operations do what you intuitively expect. When you push a value onto a stack, that becomes the top value. Pushing then popping is a no-op. An empty stack is empty, and a stack with something pushed onto it isn't empty. We can implement those stack operations however we like. Here's a class called array stack that implements the operations in a particular way. It stores the stack contents as an array of values, push adds a value onto the front of the array, and pop removes the array's first item. This class called linked list stack implements the same operations but in a different way. It stores the top element and a pointer to the rest of the stack, so top and pop are just attributes and push stores its value in a new stack instance pointing at the old one. We can use those stack operations without knowing how they're implemented. If we make an empty array stack and push two values onto it and then pop one of them and ask for the top value, we get the result we expect. If we do the same thing with a linked list stack, it works in exactly the same way. We can define more operations in terms of the old ones. For example, here's a method called size that recursively calculates the size of a stack by counting how many times it has to be popped until it becomes empty. As long as the stack has got working implementations of the empty and pop methods, we can implement the size method on top of them. It doesn't matter what stack implementation we use, the size method always works the same. An empty array stack has size zero. If we push two values onto it, its size is two. An empty linked list stack has size zero. If we push two values onto that, its size is two. So what do we mean by stack? It's really a specification. An implementation of a stack provides certain operations that follow certain rules. There are two benefits to that. Firstly, those operations provide a common interface across many possible implementations. And secondly, they allow us to build shared functionality like that size method that works with any implementation. So here's another question. What's a collection, at least in Ruby, what is a collection? Well, it's a kind of value with certain operations, actually just one operation called each. And that operation follows certain rules, actually just one rule, which is that each calls a block with a value zero or more times in immediate sequence. That's it. We can implement that each operation however we want to. Here's a hard coded collection whose each method literally calls a block with one then with two all the way up to five. Here's a generated collection whose each method calculates those values dynamically inside a loop and calls a block with each one. We can use that each operation without knowing how it's been implemented. From the outside, hard coded collection and generated collection both behave like a collection of the numbers from one to five. We can define more collection operations on top of the one operation we already have. Here's a method called select that takes a block, then calls each and accumulates all the values that make the block return true. So as long as a collection has a working implementation of each, we can implement select on top of it. It works the same for both implementations. Of course, in Ruby, we have a module called innumerable that already has select and count and map and inject and tons of other helpful stuff that all sits on top of this one each method. So what do we mean by collection? Again, it's really just a specification. An implementation of a collection provides an operation that follows a rule. And again, we get two benefits from that. Firstly, that each method gives us a common interface across many possible implementations of collections. And secondly, it allows us to build shared functionality like that select method that works with any implementation. So what name do we give these things? Are they design patterns or interfaces or APIs or duck types? All those words are kind of appropriate and they all overlap to an extent. The concept of a stack or a collection sits in the middle of all of them. In my opinion, the most specific and therefore the most accurate term is abstract data type. That literally means a kind of value which has certain operations that follow certain rules. So stacks and collections are actually abstract concepts, but they're abstract in a good way. The abstractions give us power and we expect programmers to understand them. Nobody talks about stacks in hushed tones. They're just simple and useful. Okay, so that's enough priming of your brain. Let's do some refactoring. First, I'd like to look at some code that has to deal with nils. Imagine we have a project management application with different kinds of models. Each project has a person who created it. Each person has an address. Each address has a country. Each country has a capital city. And each city has weather information which we'll just assume is a string. Let's say that in our user interface, we want to display the weather next to each project for some reason. That involves traversing all of those associations. Here's a method that does that. Maybe you'd write a Rails view helper that looks like this. There are lots of reasons not to write code like this, but there are also good reasons to do it. And anyway, people will always write code like this no matter what we say. So if we make a city which has sunny weather and a country which has that city as its capital and an address in that country and a person with that address and a project created by that person, we can pass that project into weather four and it works fine. But if we make a bad project, for example, one that has an address with no country, then weather four blows up. Now, Tony Hoar invented nil in 1965 and he now calls it his billion-dollar mistake, which he says has probably caused a billion dollars' worth of pain and damage. And this is exactly the sort of thing he's talking about. Well, there may be a mistake, but Ruby has nils, so we're stuck with them. To make our weather four method tolerate nils, we're going to have to explicitly check for them. So we need to introduce local variables to hold every intermediate result. And then we need to check each intermediate result before we try to call a method on it. And while we're at it, we might as well include the possibility that the project itself is nil. Now, this is becoming a bit of a pyramid of doom. You can see the code is drifting over to the right. But luckily, this code works the same if we flatten it. This code works, but it's pretty clumsy. And it's hard to remember to do something like this every time we might possibly have nils to deal with. Fortunately, Rails has got a solution to this problem. Rails actually act of support. Monkey patches object a nil class with a method called try, which delegates to a public send if the object is not nil and returns nil otherwise. When every object has a try method, instead of doing these nil checks ourselves, we can let try do it for us. Now we're back to just chaining method calls together so we can take the local variables out again like that. I'll just make that bigger. This is as good as it gets right now. It's better than the version with unless nil all over the place anyway. But can we do any better? Well, monkey patching definitely has its place. But monkey patching every single object in the system isn't great, is it? This is kind of a code smell, I think. Let's try not doing it. Okay. Try is gone now. You can all relax. When we want to add a method to an object, the good object-oriented programming solution is to use decoration, which is where you noninvasively add functionality to one object by wrapping it up inside another object. So let's make a decorator class optional whose instances have a single attribute called value. Instances of this class just wrap up another value. I can make a new one containing a value like the string hello and then take hello out again later. If the value I put in happens to be nil, I get nil out later. So now instead of putting the try method on the object class, let's put it on the optional class. If the value attribute is nil, it will just return nil, otherwise it will send the appropriate message to the underlying object. Now we can call try on the decorator and it will call the method on the underlying object as long as it's not nil. If the value inside the optional is nil, try will just return nil. So instead of calling try on the actual project object and then on the actual person object and so on, we can write the method like this. We decorate project with an optional object and call try on that. Then we decorate the result which might be nil and call try again. Then we decorate the result and call try on it and so on. At the end, we pull the value out and return it. It's unwieldy, but at least we're not monkey patching every object in the system anymore. There's another smell here which is that the try method does too much. We actually just wanted to refactor away the nil check, but try also sends the value a message. What if we wanted to use the value in some other way when it's not nil? The try method is over-specialized. It's got too much responsibility. So instead of hard coding the else clause here, let's allow the caller to supply a block that controls what happens next. Now we can pass a block to try and do whatever we want with the underlying value. We can still send it a message or we could use it as an argument in a method call or print it out or whatever. This ability to take a block is actually a little used feature of ActiveSupports try method as well. Now, instead of calling try with a message name and having to remember that it's going to send that message to the underlying object, we call it with a block. Inside the block, we send the message ourselves and decorate the result in an optional. We could do anything else that we wanted with the value like print out a log message or whatever. That works fine when there aren't any nils, but unfortunately we've broken it when nils are involved because we're returning nil when the block doesn't run. That's easy to fix. Instead of returning a raw nil here, we'll decorate it with an optional first. And now it works in both cases. But there's a new smell. I don't think that try is a great name anymore for this method because we changed it to do something more general than or at least something different from the main use case of its namesake in active support. Let's rename it to and then because it really just says start with this decorated value and then do some arbitrary thing with it as long as it's not nil. Here's the new version of our method which calls and then instead of try. And because we're just chaining and then calls, we can get rid of the local variables. This is verbose, but it's quite nice. We decorate the possibly nil project in an optional object, then safely traverse all the associations and then pull the possibly nil value out again at the end. So, okay. How's our refactoring going? Well, we might not be monkey patching anything and it's conceptually clean, but there's a huge final smell which is that nobody wants to write code like this. In theory, it might be better than active support's try method, but in practice it's clearly worse. But we can add some syntactic sugar to fix that. Here's a definition of method missing for optional. It uses and then to delegate any message to the underlying value whenever it's not nil. Now we can replace all of this and then optional.new with just normal message sense and let method missing take care of the details. So I'll just reformat that. There we go. This is actually really good. You can see very clearly that we wrap up the possibly nil project into an optional, then safely do our chain of methods, then pull the possibly nil weather out of an optional at the end. To recap, this is the whole thing. An object which stores a value that might be nil and a method called and then which encapsulates the nil check logic. We added some sugar on top by writing method missing and if you were doing this in production code you should remember to write respond to as well. I'd like to very briefly point out that we only need to do the decorating and undecorating for compatibility with the rest of the system. If the rest of the system passed in an optional and expected us to return one, we wouldn't even need to do that. And then we wouldn't need to remember to check for nil at all. We could write the method the way we did in the first place and it would just work. Imagine that. All right. That refactoring was very detailed. We're going to do two more but we'll have to skip the detail to save some time. Let's refactor some code that has to handle multiple results. Imagine we have a content management app with different kinds of models. There are several blogs. Each blog has many categories. Each category has many posts. Each post has many comments which for the sake of simplicity are just strings. Let's say that we want to fetch all the words from all the comments within certain blogs for some reason. That involves traversing all these associations. Here's a method that does that. At each level we map over a collection and traverse the association for each object inside it. When we reach each comment we split it on whitespace to get its words. We have to use flat map here because we want a flattened array of words not a nested one. So if we make a couple of blogs which each have a couple of categories which contain some posts which have some comments which contain some words and you can see that this accurately represents the usual level of discourse for blog comments. The words in method can pull all of the words out. We're not worried about de-tuplicating them or anything we just want the raw words. But this method has got a bit of a pyramid of doom going on plus it's hard to distinguish between the co-doing actual work and the boiler plate of dealing with multiple values. We can clean that up by introducing this class many which decorates a collection of values. Like optional it has an and then method that takes a block but this time it calls the block for every value in the collection and flattens the results together. We can replace all the calls to flat map with instances of many and calls to and then and that allows us to flatten this pyramid and if I reformat the code a little we get this. Again this is pretty clear but we can add some syntactic sugar by defining method missing. This is exactly the same as optionals method missing except it's calling many.new instead of optional.new. That lets us replace all of the and then many.new calls with just simple message sends. This is very nice. We put the blog posts into a many object traverse all of the associations then take the values out at the end and again if the rest of the system could deal with instances of many we could just expect one and return one to recap here's the class we just made. For our third quick refactoring we're going to tackle writing asynchronous code. Now I'd like to know who the most influential Rubyist is. Let's find out once and for all. We'll find out by using the github API to find the person who's made the most commits on the most popular Ruby project. When you make an HTTP get request to the github API route you get back some JSON that looks more or less like this. Among other things this gives a URI template for finding out information about any organization here. Now we know what URL to use to get information about the Ruby organization. When we make a request to this URL we get some JSON that contains the URL we can use to get a list of all of the Ruby organization's repositories. So we fetch the list of repositories which includes information about how many watches each repository has. From that we can see which repository has the most watchers which turns out to be the main Ruby repositories you might expect and we can get the URL for repository's representation in the github API. When we fetch that repository's information we find another URL that tells us where to get its list of contributors. So then we can load the list of contributors to the main Ruby repository which includes information about how many commits each contributor has made. We pick the one with the most commits, a user called Nobu, and finally fetch information about Nobu from the URL in the contributor list. It turns out that Nobu Yoshi Nakada has made the most commits on the most popular Ruby project. Thanks a lot, Nobu Yoshi. But that was quite exhausting, so let's write some code to do it for us. Let's assume we already have this get JSON method. It'll asynchronously make an HTTP get request, parse the JSON response into a Ruby hash or array, and then call a callback with the data. Or you can imagine a single threaded non-blocking event machine equivalent to this if you like. So to do what we just did, we have to get the URI templates from the GitHub API root, then fill in the template with the name of the Ruby organization, then get the organization data, then find the URL for the list of its repositories, then get the list of its repositories, then find the URL of the repository with the most watchers, then get the information on that repository, then find the URL for the list of its contributors, then get the list of its contributors, then find the URL for the list, then get the information on that user, and then print out their real name and user name. So this code works, but it's drifting to the right again. It's hard to understand and to maintain deeply nested code like this, but we can't flatten it because of the nested callbacks. Very briefly, the solution is to make an eventually class that decorates a block. The idea is that the block computes a value that might take a while to create. The run method runs the block with a callback for it to call when the value is available. We don't have time for the details, but here's an and then method that we can use to add extra asynchronous processing to the value produced by an eventually. This is more complicated than the and then methods we saw earlier, but it achieves the same thing. All of the detail is really just about how to wire up the callbacks correctly. So we can rewrite this code by putting each logical part into its own method. The code that gets all the URL templates from github can go into a method called get github api URLs. This returns an eventually which decorates a block which will eventually call its success callback with the result of fetching and parsing. We can use this as an example of how we can do this. We can use this as an example of how we can do this. We can use this as an example of how we can process callback with the result of fetching and parsing the JSON. So we can replace the line at the top with get github api URLs. And then the next bit of code that fetches the data for the Ruby organization can go in a method called get org. This returns an eventually object too. So we can replace the next bit of code with a call to get org and then the next piece of code that gets all of the Ruby organization's repositories can go in a method and then we can call it. And so on for the rest of it. I'll just clean that up. Now that we're just creating eventually objects at each step, we don't need to call and then on each one immediately. We can let each object be returned from its enclosing block before we call and then on it. So basically that means we can flatten this to get this. I'll just reformat that. This is much nicer than what we had before. So we're going to do this and we're going to do this in a way that's connected in its own method and the parts are connected together in a clean way. This might be a familiar pattern to some of you. It's similar to promises or futures or deferreds that you might have seen in JavaScript or in Event Machine. So to recap there's the whole eventually class. Okay. So what was the point of all that? You've now seen three types of monads. The first type of monad is an abstract data type. It calls it with information from the decorated object. That's a value that could be nil or multiple values or a value that arrives asynchronously. All three of these things, optional, many and eventually are implementations of monads. I think the most useful way to think of a monad is as an abstract data type like operations and then is the operation we've already seen. The other operation is a class method called from value. We haven't seen it yet but it's very simple. It just takes a value and calls the constructor to make an instance of the monad in the right way. And that abstracts away the detail of exactly how to call the constructor with a simple value which is different for each monad. In addition to those operations in order to qualify as a monad the main rule is that and then must call a block with a value zero or more times at some point. That's a much weaker guarantee than we saw for each in collections. It doesn't say whether the block will be called at all or how many times or when. Another rule is that the and then method must return an instance of the same monad and that's what makes the and then method chainable. The and then implementation in eventually and many already explicitly makes an instance of the same monad. Optional just trusts the block to do it. We could have enforced that if we wanted to. We could say raise unless result is an optional. And the third rule is that and then and from value don't mess with the value and that just means that when you construct a monad with from value you're guaranteed to get the same value out again with and then. For optional that only applies to non-nil values but you should only call them non-nil object. The big benefit of monads is that they give us a common interface which allows us to do one thing, connect together a sequence of operations. The and then method really means do the next thing. But the way it does the next thing depends on which monad you use. For optional it only does the next thing if the value isn't nil. For many it does the next thing many times for each value. And for eventually it only does the next thing once the value becomes available. And as you might imagine there are plenty of other monads with different behaviors. Like the size method for stacks or the select method for collections we can define new functionality that sits on top of the common monad interface and use it when dealing with any monad. For example we can write a method called within. Within is like sugar on top of and then. Instead of expecting the block to return a monad it expects it to return a single value and then automatically decorates it again with from value so you don't have to. Because within hides the implementation specific business of putting a value back inside the monad you can use it to write code that works with any monad. For example here's a method that takes some monad that is containing raw JSON representing a GitHub user and then it uses the within method to parse that JSON and then assemble a string containing their real name and GitHub login all within whatever the original monad was. So that means if we feed in an optional JSON string into this method then we get an optional description as the result and we know how to get a value out of that if we need to. If we pass in an optional containing nil then our method doesn't blow up because the optional monad won't let description from even try to parse the JSON it just immediately returns nil. If we make a many object containing multiple raw JSON strings then description from will return many descriptions and we can extract the actual strings ourselves if we want to. And finally if we make an object that will eventually return JSON by asynchronously fetching it from GitHub over the network then description from returns an eventual description and we have to run that with a callback to get the value out eventually. It's extremely useful to be able to write one method like this and have it work with any monad and that's possible because of the common interface provided by and then and from value and the operations we can build on top of them. Like stacks and collections monads are abstract concepts but they're abstract in a good way. The abstractions give us power as programmers we should understand them we shouldn't talk about monads in hush tones they're simple and they're useful. Now to be clear I'm not saying that you should immediately refactor all your Rails applications to use monads. I'm just using Ruby as a tool to explain an interesting idea about programming not giving you a best practice for all of your Ruby code. However, it's good to know about techniques like this and in some cases by applying the power of monads wisely we can untangle nested callbacks make parts of our code more reusable and generally make our programs better. If you want to play with the monad implementations from this talk I've also packaged them up as a gem for some reason. That's all I wanted to say. Thanks very much.