 Thanks. I hope everybody is nice and awake. My name is Ryan Muller. I work at Novartis basically across the street here. I'm a software engineer there and I write software that helps the scientists there in their research. My talk today is about BaconJS, Functional Reactive Programming and how you can leverage it in your applications along with Backbone. So how many of you are familiar with Functional Programming? How many of you like it? That's pretty good. How many of you don't like it? Oh, good. I picked out Ion's then. So basically the official definition from Wikipedia is that it's a paradigm that treats computation, blah, blah, blah, blah. The easier definition is that Functional Programming is a style of programming where functions take input and produce output without changing anything outside those functions. So here's a quick code sample of showing the difference between functional and imperative styles. This is sort of the Java version, if you like, where you sort of keep track of state yourself and you're keeping track of state in the sum variable and the i variable and we're sort of looping over it. Whereas on the right we have, we're using reduce instead, where it's much more declarative, we're just sort of specifying what we want to do and just sort of letting our reduce function take care of how we actually want to do it. If you really want to see some differences between these two styles, you can find some code that's been written in Java and in Scallet, for instance, because both of those programs or both of those languages encourage a very different style of programming. So my example has the main difference between imperative and functional programming. In functional programming, which is declarative, the focus is on what you want to do, whereas in imperative, the focus is on how you want to do it. So in 2010, we got underscore 1.0, which brought this very wonderful vocabulary for operating over collections to JavaScript and we could suddenly operate over our collections using just this vocabulary instead of having to keep track of it and do all the legwork ourselves. We got map, filter, reduce, so on and so forth. It almost becomes its own language where you have to learn the vocabulary and the concepts. And coming from this direction, functional reactive is a very natural next step to me. The BaconJS documentation looks a lot like the underscore documentation. Just in that, it presents you with this vocabulary for building programs, which you can then combine and use in very interesting ways, much like underscore. I actually think of Bacon as sort of a real-time underscore and I'll get into that with a few examples later. All right, now I'm going to show those examples. All right, so the central primitive in functional reactive is usually called an observable or a signal. A lot of the libraries out there have this really incredibly dense documentation where they use all this funky terminology, but functional reactive is really about one thing, immutable streams. If you remember two words from this talk, it's those two words, immutable streams, because it more accurately describes what you're working with. Now a stream is pretty straightforward. A stream is just a series of related events and errors that may terminate. Here's an example of a stream. This is a stream of key up events, which is very easy to generate using Bacon. I hope this diagram is clear because it's a timeline. Right now it's all the way at the right and you can see about 30 seconds worth scrolling by. I just thought this was a nice way to demonstrate the way a stream works. These are Bacon events and a Bacon event can wrap any kind of JavaScript value. It can wrap a Boolean, it can wrap a number, a string. Here I've got them wrapping a jQuery key up events. They can wrap objects and they can even wrap other Bacon streams, which is important. I'll get into that later. Streams can also have errors in them, but suppose for a second that this stream here represents a particularly unreliable weather API, we're getting temperature information from some source and the server periodically goes down. Each of those X's represents the server somehow going down or we can't contact it. Clearly we didn't write offline first app. If you look at it this way, you can think of a stream as basically a promise that can resolve or reject more than once. If you think about a promise, you have your function where you're doing something asynchronous and then you have your success callback and you have your error callback. The only difference between any promises library and Bacon.js is that Bacon might call those callbacks more than once and also Bacon gives you these really useful abstractions for converting between different streams. Oops, I skipped one. Finally, here we got a stream that ends. I mentioned that streams can end. When they end, it's pretty simple. They just don't emit any more events and you can handle this differently in your application depending on what you're doing. So we've got another weather report stream. I've gotten rid of the errors. Maybe we refactored our server or something. Really, this is all just random numbers, but suppose this is temperature. This is going to look familiar to anybody who has used underscore, which is hopefully everybody. We just take our stream and we filter it, except instead of getting a collection out of it, we get another stream. Our original stream hasn't been altered at all, but we've just got a new stream with only the events that we're interested in. I'm miserable when it's cold out, so I just decide to ignore values that are, if it's colder than 41. So that's how I wrote my filter. I'm also using the ES6 arrow functions. I hope that's okay with everybody. It's much nicer to read Bacon when you use arrow functions. So now I take it. I use another familiar function. I use map and I add the little degrees Fahrenheit symbol on the end. Now we've got a stream of strings and we can take this and we can update a div on our page. So in three quick lines, we've gone from some kind of weather event stream to get rid of the events that we're not interested in. We formatted it and now we're spitting it out onto a page. What a sign does is it'll just call a method on a div. This is just straight up jQuery. Bacon doesn't know anything about jQuery for this particular call. It's just calling the HTML method on the jQuery object that it's selecting. I've used map. There's also reduce. Reduce also has a parallel in Bacon.js. It's got two parallels, actually. One of them is called scan. We've got a stream of numbers. If you scan over them, oops, that's not a number. If you scan over them, then you get a second stream where each number is just the sum of all the numbers leading up to it. Oh, I forgot to give it a starting value. There's also another function called reduce, which is much more familiar to underscore users where it'll just give you a single value when your first stream closes. These are both useful in different instances. It just depends on what you're trying to do here. One point that I'd like to make about scan is that it creates a special kind of stream that Bacon calls a property. A property is basically the same thing as a stream. Bacon handles it very similarly. The only difference is that a stream is, like I said before, it's a series of discrete events where each event is its own distinct thing. A property is more of a continually changing value. Our first stream up there is a stream where each number is its own discrete event. The second one is a property. Each event that you're seeing there represents an updated change in a value. This is a small distinction, but it's important for certain parts of the Bacon API to understand it. We've got also a couple of ways that you can combine multiple streams. There's a merge function, which does exactly what you would expect it would. It just takes two streams and just sort of slaps them together. This is useful, for instance, if you have a search field. If you want to capture key presses, if you're looking for the enter key or the search button click, then you can take both of those sets of events and put them on one stream and then just handle that one stream and run your search function there. Very simple. There's also combined, which allows you to run a function on the latest event from each stream to create your new events. Here it's just grabbing the color from the first one and the number from the second one. Any time there's an event on either stream creates a new event on our output stream. Whoops. All right. I'm not going to bore you all with the entire API here, but there is one higher level method that you have to understand if you're going to use Bacon effectively and that's Flatmap. What Flatmap does is it takes a callback that returns a stream and it will take all the events from all the streams that that callback returns and put them on to one stream. It's a little bit of a cryptic definition, but maybe an illustration will help. Here I've got a series of URLs. Let's say we're generating them somehow. We've got user input or some kind of timer. If we take these, now I couldn't do the CSS to make a timeline coming off of a timeline, so I just cheated and added a picture. So the yellow bubble on the top there is, pretend that that's our HTTP URL here. If you map it with our just normal map function to an Ajax stream, because remember a stream is basically a fancy promise, then we'll get a stream of streams and we'll have all these sort of dangling events off of it and it'll be kind of tough to deal with. But instead, if we use Flatmap, then we get our, let's pretend that these are JSON responses, then instead we'll get our nice responses on one stream. And this is the sort of pattern that I would use to create that weather stream earlier if I wasn't using random numbers for it. So all this vocabulary, you get map, filter, merge, Flatmap, all that. It almost makes up a whole new language in its own right, with its own control flow. The fact that you have this new control flow means that you have to really attack your problems in a different way. You sort of have to get into the FRP mindset. You're not really so much thinking about past, present, and future, what just happened and what's about to happen. You're more thinking of what's going on over here, what's going on over there, because you're sort of always stuck in the current moment with FRP. Naturally, this is honestly one reason why you might want to consider not using FRP. It's because it does have a bit of a steep learning curve. It's really awesome once you've mastered it, but it's a little bit like starting off with Vim or Emacs. You're going to have maybe a couple of weeks of just really crummy performance, and then you're going to suddenly just get it, and then you're just going to take off and smooth sailing, almost. Another side effect is that you also have to learn the vocabulary of bacon. If you sit down and read through the documentation a few times, that should suffice. You sort of get a feel for the kinds of things that bacon can and can't do. Pure functional programming is good if you're an academic, if you're studying computer science, but ultimately you really do want to have side effects on the real world. Ultimately, the joke about functional programming is the reason that functional programming doesn't change global state is because nobody actually writes pure functional programs. You eventually do have to have output of some sort. As a result, you need to have some place in your application where you stop using functional programming, and you start having some kind of global state. If you're writing a background application, a really nice place to have that divide is between the internals of your models and collections and the externals. If you have bacon.js handling the sort of plumbing, then you can have your models just sort of automatically take care of themselves. You can have your views automatically take care of themselves and everything will just work. And you can just pass around those models just as you would any other and they'll just still continue to work. So now I'm going to go through a couple of recipes for combining bacon.js with backbone. Some of them are good and some of them are bad. I'm starting off with the bad one. So this is just a stream of models. This is sort of the, I don't know, maybe a first attempt at it. This is sort of why would you use backbone if you're doing this? This is you lose all the event handling stuff on the models, everything, all the plumbing that we learned about this morning at Jeremy's keynote. This is not a great, you know, you might want to just abandon backbone if you can do something as simple as this, but odds are you can't. If you could then you might not be using bacon either. A better way would be to use one model and just capture the change event as a stream. There's a wonderful little library called backbone.eventstreams. It's a file it's about this long, but you include it in your project and it'll just add this as event stream. It'll add a couple of other bacon.js goodies to your backbone items and you can get these wonderful streams just from a single call. This model is very simple, or this method of updating your views is very simple and if you use something like this to update your views, that is probably very familiar. So this would be the vanilla updating or vanilla backbone way of doing it. The bacon version would be more something like this, where you capture the event stream and then every time you see an event you would render. This is useful for updating your views, but it's also useful if you have multiple people potentially editing a resource and you might want to prevent conflicts. So instead of saving, and actually just thought it honestly just thought of this during Greg's talk, the offline first, if you have an offline first app and you save all your events, all your change events to local storage, when the app comes back on it can just push that list of events up to the server and the server can decide how to handle any conflicts, kind of like a get merge type thing. Or to go back to the view example, if you want to avoid updating your entire view, you can just do something like this and have only listen to events on a single field and create a stream from that. Now what I'd like to say about these samples is that the way that they are right now is you would probably never write them, because they don't actually do anything. I mean if you look at the model.onChange line and then the model.asEventStream line, it's longer, it's a little more unwieldy, you have all this bacon stuff that you have to deal with, so why would you do that? And the answer is that in case you want to refactor it later, in case you want to change things. Let's say you have a counter on your page, let's say you have you're counting some kind of event and you're testing and this event only occurs maybe every two seconds or so. So you write your code, you add streams in there just for the heck of it and you push the production. Well it hits production and your users start using it and suddenly you find out that this counter isn't updating every other second, it's updating dozens of times per second. So your browser starts to sweat, your CPU fare goes up and what do you do? Well if you weren't using bacon you'd probably introduce a variable at the top, you'd probably keep track of when the last update was. On every update you would check how long it's been, see if it's been beyond the certain interval and that'd be probably maybe four or five lines of code with a lot of room for error. If you're using bacon.js though, bacon actually has a very nice throttle function. So you basically just throttle based on how many milliseconds you want minimum between events. And so that way you can say okay well I just want to throttle it to every 250 milliseconds. So suddenly your UI gets much snappier. You're only updating four times a second but maybe you don't need all those updates that are making your browser sweat. So what you lose in terms of time spent learning bacon.js you gain in maintainability and flexibility of your code. One of the coolest things, oh responsive design folks. That's better. One of the coolest things you can do is there are a handful of ways that you can combine bacon.js with web sockets to sort of transparently have your streams available on either side of server versus client. This is one pattern that you can use to communicate changes in the model directly. Bacon also has a handful of other functions for converting from a callback or converting from a node style callback. There are quite a few ways that you can actually handle streams across that server client boundary. So when you have a stream on your server and you have it handled in this way you can actually take that same stream that you have on your server and do all your mapping filtering on it on the client or perhaps you want to throttle it on the server before you send it to the client. If you spend maybe 20 minutes playing around with it it's a really cool technique and it's a lot of fun that you can just sort of freely flow between server and client side if you're using node. All right I'm going to demo making a simple chat app. Suppose you've got an API like this one that's already been written. In reality we probably use web sockets for this but I just want to use this for an example. Also the chat app is just going to be one big chat room just for the sake of simplicity. So here's the the chat thread collection that's how I represent the collection. It's a little complex there's a lot of baking going on in there but I'm going to step through it step by step. This creates a property that always contains the time stamp of the last update with the server. You see we're just capturing the request event as a stream and then we're using scan to convert it into a new date so that way it'll always contain the current time stamp. If you notice before on the filter example that I had all the streams that you create from a particular stream it always occurs simultaneous unless you're doing some sort of delay or throttle it'll always be simultaneous so that time stamp is always going to represent time stamp on our request. This is very simple it just creates a stream of empty events and it's just basically a heartbeat every two seconds it sends out an empty event. Now here's where we get into the cool stuff. We take our last sync property and remember property is a continuous value so we can sample it between events because it always holds on to its value until it changes. So we take that value and we sample it on that heartbeat and we so now we have a stream of time stamps where each time stamp is the time stamp of the previous synchronization with the server. You take that and you map the time stamp to URL as the API documentation had a couple sides back and now we're sort of in familiar territory this is the the side that I cheated and used the picture on. You take that URL and you flat map it manually trigger the request because we're sort of bypassing the synchronization only because this isn't really a create read update delete app. This is more sort of sending discrete items and then we return our Ajax request as a stream and so that that Ajax stream is going to emit one event which is going to be an array of JSON items representing the messages that occurred since the last update and then the stream is going to end. So now we have an array or no a stream of arrays of JSON objects. We take that we just map it to our message model which I want to demonstrate in a moment or just show the code for it a moment. I messed up the indentation there a little bit but the this is fairly fairly straightforward and then you take that result and you call the push function on your collection. So the this context up there refers back to the collection and so now in just a handful of lines we've gone from taking our heartbeat mapping it to a URL with the last timestamp. Take that create an Ajax request create a stream of Ajax responses map them to our message model and then assign it or rather push it into our collection. Here's the message model it's very simple that's why oh I forgot about that. So here's the demo you don't need that functionality for for this part of the demo. I've got a few bots that are on there they're going to join in a second but the essential functionality for receiving messages is in place. So now I'm just going to add them out the sending functionality. I'm not using streams here you probably want to listen for an error or something here but this is just a simple post request. So then the view actually uses that merge functionality that I talked about to combine the enter key presses with the send button clicks. So we take the key up events and we filter based on 13 which is enter your key code and you merge it with the click stream. So now I can use the enter key or and the delay is because of the polling. So now because I've merged them I've combined these events into a single stream that I can handle in a particular way. Oh yeah coffee script goes very very nicely with Bacon.js because coffee script is sort of designed for functional it's ideal for functional programming and that's exactly what Bacon.js is. So any program that you write in JavaScript is going to be absolutely gorgeous if you write it in coffee script. Maybe just so maybe some of you have heard of it I don't know. So if you are looking for more information about this I've got a few resources for those of you who liked my talk those of you who didn't like my talk. This is the best explanation of functional reactive program that I've been able to find. A lot of the other explanations are really dense they sort of cram a lot of terminology in there but this is actually a gist on GitHub. I love that people are posting these sort of blog posty things as gists I know it just makes me happy on some level but I'll post these links on Twitter afterwards and this is actually this has a lot of diagrams it uses the RxJS library for its examples but it's very easy to follow no matter what library you're using because it's got diagrams it's actually where my static image diagram came from. The Bacon.js documentation is of course a great place to look it's got plenty of examples. RxJS is the implementation that I mentioned that the intro uses. If you're not a huge fan of Bacon.js but you're still interested in playing around with reactive then I would advise checking this one out. These two are really interesting. Elm is a little language that compiles to JavaScript and HTML in your browser and it's designed for functional reactive programming so you don't so much have variables you just sort of have streams as the primitives and it's a very interesting way of looking at it. The programs are a little dense to read. You have to practice a little bit. They read a little bit like Haskell which is not very well but they are beautiful little programs and there are a couple of really cool demos with it. There's also a few days ago Matt's creator of Ruby published I think it's just a specification. I'm not sure if it's the full language but information on a language that he's working on called stream and stream basically uses bash pipes. It's sort of a metaphor for functional reactive programming so you take your streams and you can use the pipe to sort of go from one item to the next. It looks a little bit ruby-ish but it's also got sort of bash mixed in there. It's a very interesting way of thinking about it. Finally for those of you who just aren't interested in functional reactive at all there is communicating sequential processes. I can never remember that acronym and JSCSP is a particular implementation of it. If you play around with ES6 generator functions then this library might be fun for you because it sort of brings a little bit of the flavor of go routines to JavaScript and let's you use sort of that style of programming. So that is basically the whole presentation. I think I'm out of time. Yeah okay. If you have any questions feel free to come find me and thanks for your patience.