 Hi Steve. That's me. That's my Twitter handle. I sometimes wear cowboy shirts. I'm blonde. I'm from Canada. I'm from a tiny little village in the middle of seriously nowhere. That's a picture of actually it's right beside the pond I used to play in as a kid. I'm looking back at my town so there's nothing there. There are cowboys. So this is a website that some friends in Canada sent me this week which I think is amazing. FarmersOnly.com. This is actually the town that I went to university. These are people looking to marry farmers or who are farmers looking to marry farm girls. This is pretty sweet. I'm not a cowboy. I'm a smug lisp weenie. I'm not a particularly good smug lisp weenie so I don't really know what this is. I did a Google image search for smug lisp weenie and it gave me a cute bunny and I know you're supposed to include one cute animal slide. So there it is. I've worked these places so I worked at adx studio ThoughtWorks and DRW trading which is in Chicago. DRW is where I've done all my closure so far. So introducing closure into an environment is kind of difficult so we started with just a t-logger. It was listening to a really terrible messaging framework called LBM which is some UDP like drop all your packets, head loss, piece of junk. So we just had an old application that was written in JRuby that would connect to this thing and dump all the messages out to a file. So we figured yeah that thing is like 50 lines of Ruby. We re-write it in closure. So we got that in 12 lines of closure. That was a start. Then we moved on to a market data republisher which is also boring. So it basically gets a data stream from an exchange and broadcast it back out to the rest of the company so that not everyone needs to connect to the exchange all at once. It was a little bit more interesting because we had to deal with Java interop and things like that. It was 300 lines of closure and then the last thing that I wrote before I left was a web application in the service. So it was basically your standard RESTful web service in behind what would normally be kind of a Rails app so we're using composure and stuff for that. That was about 2,000 lines of closure. It was actually kind of cumbersome because it was also speaking LBM in addition to HTTP. Okay, people are tweeting at me so I'm just going to... No KIA phones, they're amazing. So the last thing that was written just as I was leaving was our trade capture and position management system. So this was an application that we'd taken from 60,000 lines of C-Sharp down to about 5,000 lines of Ruby and the code samples that people were sending me after I left and joined C42 made it look like it would probably go down to about 3,000 lines of closure, which is pretty cool. So now I work in C42. I'm their token white guy. They can only have one until they hire a hundred more employees according to Indian import white people from Canada laws. So I work on Rubymonk, so I've inherited a pretty sweet code base from Jossam and Kitty and ClosureMonk is definitely coming. It's not there yet but I will build it, I promise. So this is what we're going to do. So we've basically got this broken up into two chunks. One through four is going to go really fast so I can kind of do the Zed shopping and maybe ask everybody not to be that guy. We can leave questions for the end but this is a pretty tight talk so we might not have time for questions. I'm totally happy to stop by like the coding room and hack with you on closure if you actually want to try something out after the talk this afternoon or tomorrow. So we're just going to baseline stuff, give you a quick introduction to closure, talk about list history. I think the curiosity is joy. It's the whole reason I'm a programmer. Quick introduction to functional programming as it pertains to Ruby, at least one of the kernels I think for me. And feeling good because that's also why I'm a programmer. Pro writing code makes me feel good. A little bit of metaprogramming and then a little bit of concurrency just to finish things up. So baseline, really quickly, how many people have read about closure? Anything at all, okay? So a lot of people, how many people have tried closure? Download, line again, get a REPL running, okay? So about like 20% or something. All right, how many of you have read some list literature? Sick P, Lisp in Small Pieces, anything? That's about half, all right? Do you believe this? Closures equals objects. Hands up. This is a serious one. Wow, nobody? All right, I'm screwed. Okay, so we'll do a quick introduction to closure, but maybe I need more material than this. What is this? Just shout it out. Okay, what sort of expression is it? S expression? Okay, that's technically correct answer. That's a function call. Assuming the stretch isn't a macro or a built-in special form. What is this? For anybody who's actually played with closure, you should know this one. Sorry? Conditional special form? A special form is a good guess. It's actually a macro call, which is totally awesome. So check it out. This is the macro that defines when not, which is basically rubies on less. So you have a language element defined as a macro in one freaking line, rad. Okay, so this is a bastardization of a rich Hickey quote. Basically, he says, if you want a new for loop, you can, should be able to read it yourself. You shouldn't have to wait for the compiler or the interpreter implementer to come up with Java 1.8 to do some new fancy for each. What's this? Yeah, okay, string. What's this? Keyword, read on. Some people, what's this? Symbol, right? Okay, so basically in closure, like one of the things that's going to screw you up is keyword and symbol are more or less reversed. Not exactly, but it helps to think of them that way. What's this thing? I apologize for the yellow brackets, but list, array, vector. I think I heard vector. Okay, so it's a vector. So you can write vectors and any really S expression in closure, either of these ways. So commas are white space. You can just smatter them wherever you want. They don't matter. So what's this? Close. Okay, so it's a map. Sometimes they're implemented with hashes. Sometimes they're not. So don't get that confused with this map. Two different maps. One's a function. One's a data type. Okay, what's this? This is a list. Right. In closure, it's called the seek. So that's how you pronounce SEQ is not seek. So what's this? Oh, right. Silence. That's actually good. So that's garbage, right? So single quotes in closure stop evaluation of whatever you're looking at, right? So that's not technically garbage. It actually evaluates to something valid. It just evaluates to something really kind of weird and ugly and you probably don't want to write code like that, but those are not strings. Strings are always double quoted. If you're writing Ruby and trying to write closure on the side, just start writing double quotes and all your strings and all your Ruby code because it's going to screw you up. And believe me, you don't want to spend that half an hour wondering like, why is everything not working? My strings, it's because you're writing too much Ruby. Okay, history. 1958. This guy made this guy write the first Lisbon turban on holy crap, that thing. It was mostly conceived within the span of a few years to solve the AI problem because back in those days, people had huge goals of building computers that could replicate people. They didn't really achieve that. They had instead the AI winter, which was a big disappointment for all of these guys with these big dreams, which is sad and Lisb sort of went with them to a great degree. In 1970, give or take, we got garbage collection. So there were languages that people were actually using sort of kind of with garbage collection. Memory management is awesome. Okay, except the computers were still too slow, so people were still writing C++ and crap like that. 40 years went by, we had a lot of other Lisps, none of them terribly successful. I mean, arguably scheme for academics and common Lisb for like the Lisb weenies that came before I did. So why another Lisb? Why now? I'd say two really big things. The literature in the Lisb community is amazing. Sikpi, Lisbin small pieces, the reason schemer, like these are some of the best computer science books I've ever read. They're incredibly concise. They're packed full of information and they're often like absolutely profound like bring you to the beginnings of the universe profound. Homo Iconicity, so it didn't give us robots that like wash our cars and solve all our problems, but it is this pretty powerful idea, this idea of we all really understand this in the Ruby community, right? Programs that write programs, it's awesome. Okay, so why closure specifically? Why not any of those other Lisps? Why didn't they succeed? So you might have heard this in the last few years. Concurrency is the new memory management or STMs are the new garbage collection. I think that's largely true. How many of you have a laptop in the room and how many of you with those laptops have multiple cores in the laptop? Right, friggin everybody. So this is a problem, right? Time matters. So this is I think cute, maybe not everybody thinks so. This is a clip from The Man from Earth, which is a pretty good movie that Sudhu showed me. This is where they're talking about the fact that this guy doesn't die. So he's a cave man that's lived for a lot of years. And this guy's trying to explain why that's why that's a big deal and what the deal is with time. Oh, yeah, it would help if I plugged in speakers, huh? Is there one? It took me like seven hours to carve this out of the movie, so I really want to show it. FFM Pig is hard. Actually, thank Kitty for this one. I didn't do any of it. I just watched him for seven hours. All right, so the reason that's awesome is because he's talking a lot about this idea of becoming. You can't ever cross the same river twice, all that philosophical crap. So we as programmers understand already the time matters, right? We had subversion. We had one timeline centralized somewhere and then we'd check out the end of that time or maybe some chunk from the middle of that time. But then we get the snapshot, then we mutate that and then we checked that back into the timeline. And then when Git came along, well, really, GitHub. I mean, GitHub is what we love. We don't love Git. There's a terrible interface. But so GitHub came along, Git came along, HG came along, whatever. And all of a sudden, you had timelines everywhere, right? You have a timeline on your own laptop. You track your own timeline, you follow it along, and then you push that back up into the central timeline if you want or it to someone else's timeline. However, RigDB Migrate, right? This is time management. This is state changes over time. It's your database schema, but it's really one of the most important state changes, right? When I first found out about database migrations, it was like mind blowing thing for me. It didn't happen with Rails, but so even my mom cares about time on computers now, right? Facebook timeline is actually really interesting because they've basically taken what people thought were snapshots over time and just compresses, like, smush them all into this big long timeline and say, like, ta-da, everything you've done for the last four or five years is now really, really public. And aren't you ashamed? So the solution to this problem of time in closure is closure reference types, right? Otherwise, it's concurrency and locking and Java util concurrence and stuff like that in closure. And I'm really not going to explain these are really like I've watched two hour talks explaining closure reference types and how they're built on tries and stuff like that. I'm not smart enough to explain these to you. So I'll just give you like a really dumb down version. And atom is basically a variable. Closure does not have variables. It has these things. So it allows you to perform an atomic operation to change this thing that you can view from any thread for free and safely. So it's basically thread safe variable. A ref is a little more complicated. It's more like a database table. So a do sync starts a transaction and alter is effectively like mutate that table. Your transactions can be retried, rolled back, etc. So that's kind of neat. And then an agent is this is a bastardized description and one that someone who's better at closure than I am would probably yell at me for saying but if you know Erlang actors, or if you've used event machine before this asynchronous messaging to another thread that knows how to manage itself. So the call to send to there where you're telling the agent, go mutate yourself with that function returns immediately and the agent builds up a queue of instructions and executes them on its own time. So yeah, so I wasn't going to explain this code anyway. It's filling off the screen. I apologize. You can still use Java util concurrent, right? So if you're using like volatile and locks and stuff in your Java code, I don't want to work with you. But Java util concurrent is really, really good. These are amazing classes that are well thought out and like built on real math and real smart people have built them. So you can actually wrap them. So this is a wrapper for linked blocking queue that just turns the link blocking queue into a seek. And so you pull things off to the end. I mean, a seek sort of looks like a queue. So makes sense. If nothing else, immutability promotes healthy teeth. And so even if you're not worrying about concurrency, I find that most of the bad code that I write is stateful code. And it's the states, the different states and the changing of states that makes it confusing. And that's when I grind my teeth. And certainly it's better for teeth and test driven dentistry. Curiosity is joy. So the whole reason I'm a programmer, I like to play, I like to experiment, I like to look for something new, right? So how many people came to Ruby and had never used a REPL before and never used an interactive prompt, IRB changed your lives? Okay, if you, what about Rails console, which is like a fancy IRB? Okay, a few more. So if REPL is so joyful, let's get one. If every anybody has a laptop, you can do this. I seriously recommend it like you can do it. The hotel internet is actually pretty solid. So create a bind bin directory in your home directory. If you're going to do this, start doing this now. W get this is good line again, move line again to line, make it executable. Are you remembering this? Okay. And then any line again command you run, you can do line self install, but you can just run line new project. Line again is a shell script. It'll download line again. It'll install it. And then it'll add by default a dependency of closure one three. So it'll go and get closure for you as well. And it'll install that. And you can run line REPL inside of that project. And you have a REPL. Hey, neat. Okay, is anybody still looking at the side? Or can I move on? Yeah, take pictures. That's a good idea. Okay, so if you want to hack with me after like tomorrow, I'm happy to help you get set up and stuff if you want to get your editors set up as well. Okay, emacs. So related to Oh, yeah, okay, I can't see that. That's not it. Forgive me. Oh, it's because it's not full screen. When somebody shouted me. Alright, sweet. We don't need this. Oh, demos. They're such a good idea. Okay, so I have a few things in here. The first thing is not REPL related. I just wanted you to get a REPL set up so that if you wanted to follow through any of the actual closure examples, you could. So there's this thing you can't quite see it on the right hand side par edit mode. It's been ported to Java. So you can use it in Eclipse. They haven't put it into IntelliJ yet, but I wish they would. It basically makes editing s expressions awesome. So inside of this s expression, if you can see that's an s expression ending in Z. So I can do basically control per end. I can suck things in, suck more things in, and I can do per end mustache and I can barf things back out. So the editor understands the structure of my code, which is neat. So I can also do split, and I can join them back up. So I can like move my s expressions around. And the first time that I started doing this reminded me of the first time that I used IntelliJ, which I mean might be sacrilege a little bit here, but if you've ever used IntelliJ, it's an amazing piece of software. It understands everything about your code, not just Java, right? It understands XML, it understands JavaScript. I felt a loss of that with Ruby. Like editing Ruby and Vim is just like an endless stream of characters that Vim doesn't understand at all. It gives you like some sort of fake like completion and stuff like that, but it's not great. So you get a little bit of that back. It doesn't really understand what the code is doing. But so the other things that you can do here, I've got a little REPL running on the side here. Come on, mousing skills. So the other things that you can do are you can compile this file. So yes, please save. Okay, so I've compiled the file. Now I've got my cursor at the end of this S expression. I can send that S expression to the REPL. And so there it is down there. Democore organizers. And so I'm sure I left out some organizers. I apologize. This isn't like a definitive list. I was just stealing names off the website. So now I can execute this as well. And so it's executed on that REPL and it's showing me the result down there. The other thing that I can do that's pretty neat is Ctrl C, Meta P, package demo core. Boom. So now over in the REPL, I'm actually in this file effectively now. This is like the easiest way to think of it. So now my REPL is inside the file. So I've moved inside that namespace and I can like play around in there without referencing demo.core slash slash slash, whatever. So the editing environment's pretty neat. And that was it. So this I think is the first proof that you have that S expressions and parens aren't evil. They can be used for evil things. But Lisp is not one of them. Functional programming, higher order functions, real higher order functions. So functions that can take functions as parameters and return functions back to you. Okay, so you can see most of this code, I apologize. So here are some cliches of Canadian culture. I'm mapping over them and up casing them. So I'm shouting. You can turn that into map, ampersand, symbol, upcase, right? This is a special thing in Ruby. This is not consistent syntax. This is a special way of getting to two proc. And it requires a little bit of a detour. So what if we have an object that we want to pass into this, this map that we're doing, and we want to call a method on that object with our object that we're mapping over. Well, now we have to go back to the block form, right, we can't use to proc anymore, which means that we've effectively like taken our fake higher order functions and turned them back into like explicit lambdas, which still works. But it's not quite as cute. So enclosure, you wouldn't generally write code that looks like this, you don't write a lot of object oriented code and close you write some but the majority of your code is going to be built out of much smaller pieces than full on classes. I'm just doing this to maintain parity with a Ruby code. So enclosure, I can say, so this is a interface basically on the top protocols are more powerful than interfaces, but it's not worth explaining why types are basically like classes. So I've got to like type Canadian, and I create Stephen Harper is our terrible, terrible Prime Minister. He's an evil man, and I can't wait for him to go away. So Harper is Canadian. And say as Harper, I can actually construct a new function that I can pass in as a parameter to map. And this is really powerful, not in this example necessarily, but when you start piling these things up on top of each other, you stop needing to do do and do and do and with lambdas cascading like you do in Ruby. The spectrum of functionalness. So the first time that I came to Ruby, I thought it was really, really awesome that Ruby returns the last expression by default. That is awesome. It's really awesome because it's a functional concept, right? Every method you write returns a value, which encourages you to write functional code. But it's not quite as functional as forcing you to return only one value from every function and making the purpose of every function to return a value, right? And then if you go further down the scale to Haskell, then you can't do any mutation at all. And the only reason ever to write a function is to return a value. And I'm sure Haskell is very awesome. And one day I'll experience that for myself. But yeah, this is how I tell you that I don't know any Haskell at all. So I think the reason for this maybe is because that Ruby was written in Japan by this adorable fellow and the Japanese like Sushi. And so that is squishy. And Ruby is squishy. And so the difference being, sorry, the thing about Ruby here is that all of these things, these innocent looking statements are squishy, right? They're potentially mutating things. They're potentially changing state under the covers. So potential mutation, potential mutation, that last line is definitely mutation, right? You are assigning a field, which is a shame. So closure was written in America, America, by this guy, who is a scientist and a philosopher. And so closure tends to be sciencey and philosophy. So you end up with stuff like this. You have let bindings, but they are not assignment. Once you assign that value to general sales tax, general sales task is like that forever. It's not entirely true. You can define general sales tax as dynamic if you need that to escape out of your safety zone. But most of the time, you're never doing that. And all list functions have a single return point. So you're taking that idea that the last expression you evaluate it is your return value and just like taking it to the next level, you're saying the purpose of these functions is to return values. Feeling good. How many people is only like making you raise your hands a lot? And like I just want to make sure you're awake. So how many people have read this book? All right, a few. How many people have read this book? Discipliningly few. Okay. How many people have read this book? Right, most of us. How many people think that this was the original design patterns book? Right. This is the original design patterns book. And probably there were white papers before that. But I mean, this is kind of like the canonical work. So I went to go read this book and I read the forward, which is written by Christopher Alexander, who's an architect who had all his ideas stolen about design patterns from architecture, which is like a legitimate field. Or so he says, as opposed to software, which he's like, I don't really know if you guys have design patterns. So his forward basically bashes software and says like, architecture has been around for thousands of years. We have patterns that have come up that have emerged out of humanity. Software is not quite there yet. So it's like, you know, his forward is pretty well written. I'm going to go read his books. They're amazing. Like better than any software book I've ever read better than almost any other book I've ever read. So he has one book of pattern language, which is almost 300 patterns of like how to design human spaces, how to design buildings. So he's got things like no building over four stories tall. He's got things like plants in the windowsill. He's got things like old people everywhere. It's a beautiful, beautiful book. I would really recommend you read it. And he comes up with this notion, the quality without a name. Something that you like, something that you're attracted to, that you can't point to and you can't label and you can't name, you can't identify, but you can feel it. I think the French call this je ne sais quoi. And in this book, he asks explicitly, so this was actually written after a pattern language, but it sort of was a prequel, what feeling do you have about a building? So once a building serves its purpose, how do you feel when you're in it? How do you feel when you're outside of it? How do you feel in any environment? So how do you feel about this code? Does anybody use Mailbox? JRuby, Mailbox? Nobody? Okay. So this is cool. I'm introducing this to you. So a good buddy of mine, Patrick Farley, and actually another good buddy, Joel, wrote this together at DRW. So mail slot, it's more powerful than this, you can mark it up, you can tell where to put the exceptions and stuff like that. But mail slot basically says, when you call this method, cross the thread boundary, start a new thread up, or you can use an existing thread, but basically return immediately from the call to log and this thing will run on another thread. This is friggin beautiful, right? On the outside. I mean, it's two lines of code and you've added pretty safe concurrency to your Ruby application as long as you're using JRuby, caveat. So I feel pretty good about that code. I think it's awesome. So that was the first thing that I was looking at there. Mailbox. So this is the inside of Mailbox, right? This doesn't look like Ruby to me and it doesn't make me feel very good, because this is Ruby metaprogramming. It looks like Python to me, maybe, but I don't really know Python, so that's like not fair. But it's got like a lot of these double underscores to make sure you don't collide with anything in like a different namespace that you're being imported into and it's doing a lot of like construct strings and then turn them into symbols and then send them to something else. A lot of like kind of like dangerous feeling garbages stuff. And it works. It definitely works. It's well tested, but we're looking at that code specifically doesn't make me feel good. So I mean I don't know how you feel about it, but it's an open question. So metaprogramming, right? Metaprogramming enclosure. How much time do I have? Alright, like barely any. So here's like a really sort of canonical example for me, because the first time I ran into this I was actually trying to do this. I was trying to define a method with define method, which is itself took a block. Which is a block taking a block. In Ruby 1.8 this is impossible, right? You can't do it. So at the time I was using JRuby and we were using Ruby 1.8 standards because it was safer. So it was literally impossible. There was no way to construct this. So Ruby 1.9 it still doesn't let you do yield. So you get the local jump error. Ruby 1.9 does allow you to name the block and then call it explicitly. So that's an improvement, right? But the reason for this I think is inconsistency of syntax, right? So they're all just lambdas. They're all just functions. But for some reason we have all these different ways of coming up with this. And I think that this sort of thing is what gives Ruby grammar dependency. You can't really see that very well, but it's Ruby's grammar dependency graph and yes part of it is what makes Ruby powerful, but it's also kind of scary to look at. So this is how you define a function enclosure. There's only one way, fn. So fn in square brackets, your parameters and then your code and it'll return a value. Pretty simple. So if you want to give your function a name you def the name and attach it to a lambda. Or you can use def n which is just a function that does exactly that. So here's a little bit of metaprogramming enclosure from the outside. So like mailbox we're like looking at the consumption of our metaprogram code. So def project is just a map, not a hash, a map. So name and path pretty straightforward. And then we've got this thing that's just like a cascading series of functions, right? And it looks pretty lispy and pretty annoying with a lot of parentheses. And if you haven't written lisp before, those are going to be scary to you, or at least they were to me and they look kind of bad. And so what closure has is this thing called the threading operator, which is dash greater than. And so it basically just flips that other form inside out, right? So instead of like the innermost parent is the thing I do first and then I go out and I call a function on that and then I go out and call a function on that. Instead I just say thread and take that object project and just pass it into the first function colon path so that will actually extract path out of the out of the map. So lookup path and then it'll take the return value of that and pass that into the next thing. So pass that into IO file, take the return value of that, pass that in the list files, etc, etc. So what's interesting is you get to the end and you can actually use half formed functions, right? So ends with JPEG is not a valid function. It's missing a parameter. That parameter is the first parameter which is the result of everything else that's going on there. So actually if you do macro expand on this arrow operator, you get the thing up above that's a little bit uglier. So you have the same code but it just looks a little different. This is def macro the threading operator. So the first one just returns itself. The third one is just doing was a little bit of recursion. Ignore the width meta there. That's just some metadata is like a closure thing so that you can make programmer constructs like hash code orthogonal to everything else. So it doesn't mess up your your code that you're actually trying to use for users. So this is basically just take the first form, take your result from the last thing, X, stick it as the second item in that list and then do the rest. So that's pretty sweet. That's like what five lines that's pretty powerful. Right. So you can't get there from here in Ruby. You can't do this. This is a new language construct. Ruby can come pretty close with blocks and do cute things where like you with something and you start a transaction and you close it automatically once the block is done. But that's kind of the extent of it. So there was a really great talk at Closure Conj and I'm coming like dangerously close to the end of my time. But given by Christophe Rand, if you don't read his blog, I would recommend it. The guy is brilliant. He's the guy who wrote the wrapper around Java util concurrent link blocking queue. So he gave this talk to the first closure Conj basically saying DSLs are not macros. Right. This is the mistake that everyone makes when they come to closure for the first time. They're like, Macros are super powerful and I can do everything and like, yes, they're super powerful just like Ruby Meta programming and they're dangerous just like Ruby Meta programming. And so what you really have is this spectrum of APIs, right? APIs, DSLs, same thing. Just less trendy. So at the end, you have compilers. So if you really need to define some new language syntax, you need to make your code smaller. You write a compiler. You can do that. Or in a language like Lisp, you can use a macro or in any language, you'll have hopefully a function available to you. And at the very bottom, you just have raw data, right. And so he says, push that down as far as you can because that makes things simpler, easier to manipulate. And so basically the opposite. Yes, Macros give you infinite power almost, but try not to use them. So this is a little snippet. It really did the code doesn't matter. It's just a function from the closure script compiler. So all it's doing is saying, take in some closure and emit a string that's JavaScript that means the same thing. And it's fine. We all understand how compilers work. They're boring. Okay, Macros on the that's nice. It fills over. So macros core dot match is probably my favorite closure library right now. David Nolan is a JavaScript programmer for the New York Times. When he came to closure, and he started reading papers about predicate dispatch and was like, oh, matching libraries are neat. And closure doesn't have one. It has multi methods, which are way more powerful than type based type based dispatch, but not as powerful as full matching. Right. So Erlang, OCaml, these languages can match things as you enter into a function and dispatch on whatever crazy rules you want to come up with. So he's like, we're just going to read about all these different languages and read a bunch of white papers. And I'm just going to build the matching library that I want. And so he writes core dot match, which does this. So it takes these values. X is true. Y is true. Z is true. And it filters them through this thing. And it figures out which thing you want on the right hand side. Okay. And so you want four. So this example is pretty boring, right? Because you could write this with a plain old conditional or any other way that you wanted in, in Ruby wouldn't matter. But you get here. And so now you have this supercharged conditional that doesn't require conditionals. And we've got all sorts of dangerous stuff on the right hand side. Right. So if you tried to write this in code with a function, all these things would execute because they'd be evaluated. The macro stops these from being evaluated and makes sure is that you only kill the thread. You only do the last one. The way to do this in Ruby would be to delay execution with lambdas, right? But you couldn't get this concise syntax. It's super cute. And it's 1761 line. Like he's basically taken the best features of Erlang and OCaml pattern matching, smushed them into closure in a library, no less an optional library in less than 2000 lines. That's nuts. Yeah. So do we navigate disappointment? Do we choose design patterns that get around the limitations of our language? Or do we choose a language with fewer design patterns and more powerful constructs? Or do we just eliminate disappointment all together? So these are macros, right? These are things that, okay, I'm becoming really close. I apologize. I might have to skip the last bit. I don't know when I get cut off or they start ringing the bell or whatever. But so all these things you would think of as part of a language, part of the compiler, part of the interpreter, they're not enclosure. And so like four block comments, start a transaction, while loop, these are all macros, but get to the bottom to find a function to find a lambda is a macro. Awesome. That's super awesome. So that thing again, I picked up this book off of Tim Bray's blog. It was one of his recommended books of last year. It's a hilarious book. Whether you speak Arabic and what other languages he uses or not. Docher basically, I think I'm pronouncing his name correctly, docher. He basically takes himself to task in coming up with an explanation for how we have language as we have it, how his language emerged. And he talks about when he was a kid and thinking that some guys got together in a room and designed all the languages and like, okay, now we'll go out and prosper or whatever. And he comes up with this conclusion that inevitably languages evolved, right? Over time, languages mutate, they smush into other languages, they die off. They have lifespans. And I think that this applies to programming languages as well. We, oh, sorry, I don't have another slide for this explanation. We don't know now what we will know next week, what we will know next year, right? So why program in a language that confines us to the decisions made in the past? Why not give ourselves a language that allows us to change the language as we learn new things? Give us, give ourselves an evolutionary language. So functions. Really quickly. So this is Ring. It's loosely based on rack, so it's basically a rack inspired rack equivalent. It's not even really a library. It's just a consistent form. It's, it's just a, what do you call it in Rails? That other word that starts with Z. Convention. That one. So it's basically define this function handler. It takes in a request and it returns you back a map that's going to be turned into the result that you passed back to the browser. And then it's got this function or a series of functions that look like this. The middleware, right? They take in the handler and then they return you a function which takes in a request. And so the function you're returning is basically of the same signature as that primary handler function. And it just allows you to keep cascading these functions on top of one another and look, arrow operator allows us to pile these things up on top of one another in a very like succinct way. I think that's very cute. And so I just wrote one as an example there. It just says if you send me a get, I send you a teapot. Really helpful. So data structures. Once you get to the bottom of that chain, Christoph, Christoph Grand's chain, you get to this, right? A lot of Ruby libraries that are meant to be declarative are written in functional style with a lot of lambdas. Time? Or really time? Okay. One more minute. Okay. Really? I only have one more thing. Okay, okay. So the bottom is the data structure that represents what we're using lambdas for in Ruby. We could do the same thing in Ruby, but I don't see people doing this a lot of the time, right? Just saying we have a bunch of arrays inside of arrays and they represent the HTML that we want to output. So this is just data, right? You can manipulate that however you want. Messaging concurrency. So nobody's used mailbox, but people are probably used event machine, I'm guessing, for passing things off. Okay. How about if people want to see this demo, you can grab me. We'll go to the hacking room or whatever. So I was basically just going to show how agents work with a little thing, but that's mostly boring anyway. So if you want to know what to do next, if you're as excited as I am about closure or getting there, I'd say that Relevance's lab repl is a great place to start. It's a really, really easy way to get into closure and by the end of the lab repl, you've built a web application, you've done all sorts of crazy stuff. The joy of closure is the only book on closure you need to read, but you'll probably need to read it about seven times and here are some things that I think are important and I apologize, but we don't have time for questions. So thank you.