 Thank you for coming here I'm excited to talk to you about Ruby lambdas first. I want to apologize in advance for my very thick American accent I hope you'll still be able to understand me and I do know that I can be quickly and sometimes not so clearly so feel free to stop me anyway Who here has worked with Ruby before at all? okay, and Have you worked with Ruby like anybody worked with it quite a bit Okay, anybody explore lambdas with Ruby at all Okay, good and For you others. Are you mainly involved in object-oriented development? Java C sharp that kind of language Okay, good. So we have kind of a Equal mix I guess First I want to say I am not an expert on functional programming I've been to study groups for Erlang and closure and really enjoyed it and I've been exploring functional techniques in Ruby But I'm not a guru and so Please keep that in mind Lambda is a free floating function. It doesn't belong to a class or an object. It's not even associated with one Meal for it says Explains functions in a functional language are considered first class Meaning that functions can appear anywhere that any other language construct such as variables can appear and we'll see throughout the presentation how Lambdas are really very Flexible you can put them anywhere unlike methods which have to be in certain places And by enabling functions as return values and I would say also parameters and variables You can create the opportunity to build highly dynamic adaptable systems. We saw a lot of this in the last presentation about Java That's for me, I haven't As they say drunk the functional Kool-Aid completely yet I'm very excited about it, but I still have one of my feet in the object-oriented world and So I look at functional programming as a complement to object-oriented programming and feel that There's a place for both of them This is directed to Rubius. Do you remember when you encountered code blocks for the first time? And that they were very confusing at first. I know they were for me the syntax kind of confused me It wasn't really clear from the syntax. What was happening when? It was later that it I realized that this is just a block of code that was being passed to the method And the method could do whatever I wanted with it But you persevere it and you master them was it worth the effort Probably so in fact Ruby without code blocks would be a very different language Well coming from code blocks lambdas are the next step in that progression code blocks are kind of co-literals, but lambdas are objects that contain code and There's really a lot of similarity between them So whereas most Rubius avoid lambdas thinking that there's some functional corner of the universe that doesn't apply to me They're really already in that functional universe using code blocks Many Rubius will complain, but it's not idiomatic Ruby to use lambdas because nobody understands what lambdas are Rubius don't already know what it is. You will confuse them. They'll have to learn something new something else new This will discourage people from entering the Ruby world But I believe that the benefits of using lambdas are so compelling that it's worth Deviating from that idiomatic Ruby or even changing it Why should the rubius care about lambdas? lambdas can help us Simple hire code make it more extensible and we can become more productive and therefore have more fun doing what we're doing We heard a little bit about it before Unnecessary complexity is our enemy software developers We we do or should be doing our best to eliminate unnecessary complexity We strive to maximize the ratio of functionality over complexity If we absolutely need some complexity to get some functionality then we can live with that But if it's just there because we haven't taken the opportunity to improve our code, that's not so great So we're always trying to maximize this ratio so that our code can be highly functional and yet maintainable and extensible and comprehensible to the reader local variables have been around for a long time and I'm going to be a little bit sarcastic here when I when I say this When we define variables in Ruby, we define them all as instance or class variables, right limiting their scope By declaring them local has no value to us Does that make sense? No Of course, we want variable to be local because that limits their scope and makes them It makes the interrupt it Increases the number of possible interactions in the code which makes it simpler which is good And yet that's exactly what we do in languages like Ruby and until recently Java with instance methods Any piece of functionality except for code blocks is in a method and a method can only be in a class It can only be an instance method or a class method Define at this class level so every time you want to extract functionality into a method You're adding to this list of instance methods and when the reader comes and looks and reads your class He or she will see a long list of methods and there'll be a lot there and it'll be confusing One measure of complexity is the number of possible paths of interaction so let's say each of these circles is an instance method and The possible interactions are indicated by the lines between them and The method call can go in either direction So for each line we multiply by two to get the number of possible interactions Also, we can multiply n times the quantity and minus one and with five instance methods. We get 20 possible interactions We just five that's a lot Wouldn't it be nice if we could make method like things local to a method and In practice, I find at least I don't know about you but in my experience It's very often that a method is called by only one other method So it's kind of like the implementation detail for a member and so why not make them local methods? If we can do that and here we show what that might look like you have two lambdas That we remove two methods and make them two lambdas inside one of the methods. We now have decreased our count of instance methods from five to three Decrease the complexity from 20 to 6 that's over three times That's a lot So this is what it might look like let's say I had these lambdas Fetch type one data fetch type two data is doing two different types of information over a network and then some of the integrate the data and Then I can tie them all together at the bottom here These are implementation details for this out of method This could be the public method and this just the internal implementation detail So somebody reading the class wouldn't need to see this these as instance method So for all you oh developers, is there anything about the structure that looks familiar anybody? Does it look like something you're familiar with? for the indentation and the The subdivisions of functionality class It's kind of like a class right? So whereas before we have This here as a single method and these lambdas within the method instead We can have a class and those lambdas become instance methods of that class And that's really what object-oriented development the design is all about It's it's making small classes that do one thing. Well and because they started out writing this this big method with lambdas and Subdividing the functionality into units of like related behavior It was a very trivial matter to convert that to a class when we encourage ourselves to Convert code to classes we wind up with better quality code How many times have you seen really large humongous? Classes that are doing way too much for one class But to refactor that would just be so difficult that you never do it because you wouldn't have time If you start out at the beginning by using nested lambdas, then you already have that class structure So in in this case I might decide well, you know what? This is getting really complicated This really should be a class. I'm not anti-class or anything. Sometimes it should be a class So if you start out with this lambdas design, it's easy to make it a class and In this class this run method might be the only public method these kids all in private Feel free to interrupt with questions or another nice thing about using lambdas is that Once you have packaged your code in a lambda You can pass it around and do things with it that are easier than if it were just the longest block of code as an example At one point I realized I'm doing these network accesses. Why am I doing them in sequence when I can be doing them in parallel? Most of my time is just waiting anyway, right? so Since these are already lambdas it became trivial to put this structure around it To to do that and to threads One of the things that's been mentioned earlier today, and that I believe really strongly is that you should a Given chunk of code should have one Theme different things should be in different parts of the code Here I have the mechanism for running two threads and waiting for them to finish The only thing I have that says anything about what's actually being run in those threads is The minimum possible thing I could have which is the name of a lambda There is no implementation detail here So theoretically if this became a pattern that I was using really often I could extract it out into some methods somewhere and some utility things and Refactor it even more So let's step back a little bit and look at the syntax for defining lambdas and Ruby Ruby moved from version one eight to one nine several years ago And it was a pretty big change in the language and some new syntax was added Before one nine, this was the way the only way you could define a lambda use the lambda It looks like a keyword, but I believe it's actually a method on the kernel class In any case, you would say lambda and then curly braces or do and And any code would be inside the curly braces or the do and for those not familiar with Ruby These are pretty synonymous the curly braces and idiomatically if it's going to be only only one line We use the curly braces and it's going to be multiple lines we use to end Starting in one nine. We have what's called the stabby lambda syntax, which is this arrow here And I like this better because it's kind of like a picture rather than a word And so it stands out to me and if we have parameters in the lambda then Before one nine, we would have to define them like this And this is exactly the way it's done in the code block But starting with one nine we get to do it this way and this is exactly the way you would do it in a function method boring details, right? One of the first things I did with lambdas when I started experimenting with them was use them in unit tests There are many times when you might have a method that you've designed to raise an exception if they gets a bad input Something bad happens You might want to test that that really does happen when it's supposed to and our spec has a special Method here that you can use raised error You can pass a lambda in You won't get executed until it's safely inside the aspect framework and our spec will look to see if a result in error was raised and Either pass or fail the test accordingly The simplest thing I could think of would be to divide one by zero to generate an error Lambdas are also assignable. We can assign them to variables Here we have a lambda that takes a name as a parameter and Returns a string containing that name And again for those not familiar with Ruby when you have a double-coded string This pound curly braces will enclose an expression that will be evaluated and then that pound curly brace String will be replaced with a result of that It's called interpolation. It's a fancy word for Substitution and then we can call it in several ways in all versions of Ruby we can call it with the call method and The square brackets and starting in one nine. We have the dot per end notation, which is the one I prefer The square brackets I really don't like using that because Square brackets have a special meaning to me and I think to most people It's the way we get a value out of a bigger thing such as a hash or an array and so I Hardly ever use it, but I'll show one case where I do A little later lambdas are closures, which means they carry with them the Context in which they were defined and by context. I mean basically the local variables. So here we have statement n equals 15 and we have a lambda Quits just is like a print print line and Java we output that value So we define a lambda here and then the dot parent calls it right there and The result we get would be 15 because it can see this This is it's gonna be a good thing, but this can also be a bad thing you may not intend To access that variable that's in the outer scope. For example, what if you have a lambda? That uses an intermediate variable what it thinks is a local variable But because it has already been defined in the scope instead it's modifying that thing that was already created outside the scope In this case, we have n equals 15 and then we run this lambda where we assign the string to n And when we output n we get the string. I just overwrote n Because we've overwritten this There's another thing that you can do with lambdas. That's can be risky can be powerful But also risky, which is kind of like the theme of Ruby. I guess is The lambda you can get the binding of a lambda by calling its binding method the binding contains the local variable and Binding has a method on it called eval or you can give it an arbitrary string of Ruby code And that string will be evaluated in the context of that binding So since name is in the binding of this lambda We can We can run this and we're going to overwrite name with another name And then this will print out here now This doesn't seem too harmful, right? But if you have several lambdas that you define in the same binding and one of them changes value in the Binding that's shared by the other that could be kind of dangerous So Ruby may not be the best functional language to use for functional programming but just be informed and Choose what you think is best. I love Ruby because I think it's an awesome general purpose programming language and to have the Functional aspects added to it. It's really It's really wonderful We can get around that problem by Specifying in the parameter list. This isn't really a parameter, but this is where the parameters would go if there were some We can specify that this is a lambda local by Having a semicolon and then the name of the variable that we want to be considered local If there were other parameters, they would be here before the semi-colon So here we're saying hey if you see and in this lambda Don't use an end from outside create a new local and We can see by this code that that work Because when the output and it's still 15, you know, we execute it Does that make sense I mentioned that there was there are a few cases where the square bracket notation might make sense And here is one of them. I have been working with a data set that was several levels deep and hashes and arrays and Accessing anything with square brackets is a real pain when you have to use five of them. And so I thought well Let me see if there's a better way and a colleague started this and I kind of carried the ball a little further and wrote something Like this where you could separate the levels with a period or any arbitrary Character and it would do the navigation the descending for you so here's a Collection this is an array of three elements. The first is a string second is a hash the third is another array and This array has three things in it And so if we access one dot color one is this hash color is this and we get yellow two dot two Two is this array and the second two is the last element of the inner array you get 75 so in this case accessor is a lambda and Normally, I wouldn't use these square brackets But because it's doing something that you would expect something with square brackets to do I think it's a good idea to use them in this case in Ruby We have like in Java we have public private protected methods the meaning is a little bit different, but almost the same But you can get around that privacy because With any class or any object you can call its send method and give it the name of a function And it will call that function even if it's private if you really want something to be private You can make it a lambda local to that method and then It only lives for the lifetime of the method call so there's no way you can reach in and find it and get to it I I gave this talk in Pittsburgh a couple months ago, and somebody pointed out After the conference he did some benchmarking and found that Creating and destroying a lot of lambdas actually takes time So that's something to be careful about if it's something that you're going to be doing a hundred thousand times You might not want to create the lambda inside the method You might want to make it in that case an instance method instead or move the lambda outside and assign it to a constant of the class In most cases the the time for creating destroying the lambda object is very minimal compared with the work It's actually doing and it doesn't matter, but in some cases it might matter I'm trying to demonstrate that I'm being objective about this. I'm not saying that you know the review is Perfect or the functional programming and the review is perfect Self-invoking anonymous functions. We actually saw this before But this is when you create a lambda and then you call it right away Here's an example We have this lambda that contains this code and then we call it right away Anybody know why we might want to do that because we want to show off for pretenses. We know what lambdas are. Is there another reason? What about these local variables here? Well, if this isn't the lambda these local variables will persist past the execution of this code But because this is a lambda These are local to the lambda and never go beyond the outside of the lambda They don't exist anymore after the lambda is finished running and that can be pretty handy In fact, copy script uses this exact technique so that when you write a copy script script You're now polluting the global JavaScript namespace with your variables lambdas are a natural for event handlers Here I'm defining an event handler that when it's called with an event will just output a string Saying this event occurred and then the event that occurred and then we can pass that to a method called ad event handler and Lambda is our first-class objects. We can pass them around and they can be held on to for later use and Called we can make this even more concise by defining a lambda right here without even using an intermediate variable What about when we have to customize behavior? We saw in the last episode in the Java session about filtering and This is a pretty common theme In fact, you know, we talked about it last time and this time As object-oriented developers the first thing that would come to mind would be polymorphism. We write classes that specialized the behavior so They might look something like this if you want an even filter and an odd filter we write a Class with a consistent function name that function name will be shared by all the other classes That we're using for this purpose and the name here is filter So we define these classes and then we instantiate them and then we can use them kind of a lot of code For something really simple If instead we use lambdas, it's much much more concise Here we have the even filter and the odd filter and we use them and it's very very concise and another nice thing about using lambdas rather than classes for this is that You can use lambdas to compose lambdas. You can have compound filters where you you have a Method or lambda that takes a bunch of filters and then combines them all together in one big and or something like that You can do a lot of things with lambdas more flexibly than a class method. This is method of a class duplication Where we're going down the same road we went from the last session again, but Here are some methods that Double quadruple double triple and quadruple a number and as you can see there's some duplication in these methods the times n part specifically Normally this wouldn't be really a huge red flag It's not that much duplication, but it helps us illustrate the concept of refactoring out the duplication So let's take a look at what we might do. We can use partial application or currying and with partial application We have here a an outer lambda That creates the returns an inner lambda We call the outer lambda with the factor the number that we want all numbers to be multiplied by It creates a lambda that when called with another number Multiplies it by that number that we will pass in when the lambda was created So we can get a tripler by calling this with three Then when we call it with a number we get tripling up a number And in this way the guts of the logic for all of these multipliers is in only one place similarly because Landers are first-class objects. They can be returned by methods So it doesn't have to be a lambda that creates a lambda. It can be a method so this is exactly the same thing except as a method instead of a lambda and Note here. We don't use the dot for it. We just use the regular Curring does the same thing but in a different way we start out with a function that takes all the parameters necessary for the computation Namely here the two and then we pre-fill one of them one of those parameters And this returns a lambda that we can then call with the second number to get the desired result Curry is a method on the proc class Which returns a lambda which went called with a method return with a number return with a value to pre-fill Returns another lambda predicates, I should have gone before the top of toast predicates are lambdas that return a true or false value and One of the common uses for predicates is filtering Here is an example of a function a method that takes a filter as an optional parameter in Ruby parameters can be optional if you say parameter name equals expression then if this Parameter is not passed then this expression will be used This is a lambda which takes a message as its parameter and unconditionally returns true So this is a default value It's like we heard in the last session rather than using nil and having to check for nil Instead we can just give it a default lambda and have a call that default lambda and That would just let everything through it would affect the unfiltered Then the way we call the filter is pretty simple filter dot friend parameter so This message will be added to the messages array if when we call filter with the message filter returns true pretty plain English right using the word filter. It's pretty apparent what it's doing. It's not complicated However, many Rubyists will say why use lambdas when you could do the same thing with a code block and You can't this is how you would do it with a code block But I ask you which way it looks clearer to you There's nothing in here. This is anything about filtering There's nothing here that indicates that you're passing it to the method because when you pass a block to a method You don't need to specify anything here so and The other thing is it if if a method should require more than one of these then you can't use co-block anyway because You can only pass one co-block to a Ruby method a common theme and the functional programming that I found is Create self-contained things that do one thing. Well, like the unit scope and Try to separate unrelated code out Into separate areas. I saw a really good analogy on Twitter said something like a fully structured code is more like mangled coat hangers than spaghetti because the spaghetti you can pull one strand out pretty easily But the coat hangers it's not so easy if they're all kind of intertwined really He's in the park. Am I speaking clearly enough by the way? Okay, good. I just want to make sure Okay So here's an example of doing that I was writing some code that was doing some network accesses and then processing the results and Then I realized that I should really be chunking these messages into blocks and so For my previous years as a Java developer and before my first gut reaction was to do it right there in the same code Just add the chunking part to the same area of the code that Fetching but then I realized hey wait a minute. That's not clean what I should really be doing is separating out the The concept and the implementation of the chunking From the thing that is actually being done with the objects in the chunk Why should they be in the same place? Shouldn't be and when we separate them we get all kinds of opportunities for reuse and simplification so It went even further because I then I thought well. Hey The chunking thing Has logic that it has to know when to get the chunk how to dispense the objects and keep track of things and stuff But why does it need to know how to get the chunk? Why can't that be configurable, too? all right, so this is the signature of the Buffered enumerable, which is the name of that class method, it's a class method that creates an object and It takes a fetcher Lambda which is the implementation of how the record should be fetched and Optionally a fetched notifier lambda as well and this one I realized that I needed this when I Started the unit test that I thought how am I going to know when it's fetching when it's doing it the right way So I thought hey if I put a fetched notifier in there that's configurable then I can test it and people can use it for logging and Maybe displaying a message to the user or private bar, etc We talked about lambdas as nested functions already, but here's another example of how it can clarify your code Again, we try to separate high from low-level stuff and we try to separate unrelated things from each other the task of formatting the string really has nothing to do with what's in the string Plus by making it a lambda here. We eliminate the duplication so that this logic is only specified once And we can call it three times here lambdas when you have lambdas you can't just Specify them without the parentheses and expect them to be called as you can with methods Because without the parentheses it results to the lambda itself Methods are not always an option as I said before you can't define it just anywhere And here's an example where I defined it in an R-spec test And then I ran it right after I defined it and got an error saying undefined method so That was kind of frustrating and I found you that you could actually move it somewhere else and would work But then it was further away from the code and it really wasn't a great solution Lambda on the other hand worked great. I because you couldn't define that anywhere. You want so here's a lambda and I called it here and as you can see We can use a lambda where a code block is expected By putting an ampersand in front of it. We can use a method where a lambda is expected by doing that and I'm gonna pass over this unless we have more time later lambdas and prox are selfless I Was surprised when I tried this I tried out putting a self inside a lambda and Expected to see some 2s representation of the lambda. I didn't Instead you get the The object in which it lives in which it's enclosed. I was writing some code that modified Class attributes and private and public and that kind of thing and wanted to test that and in the tests I wanted to be able to set up and tear down classes before and after each test and so I tried defining a class inside a method and it didn't work Can't do it but with a lambda You can do it Here we have a lambda that defines a class and if there's no error and when you Instantiate that class it works So that's kind of an obscure thing, but that's helpful to Transform chains We heard about predicates already transformers or things that change a value from one to another When we think of iteration and enumeration we usually think of taking Data objects and passing them through something doing something with that, but if we rotate that 90 degrees and instead Take a single data item and pass it through multiple transforms So we're kind of switching the noun in the verb then We can create these little processing systems that can be very configurable That too is a bit obscure, but it's an interesting use of lambdas You just have an array of undefined size of lambdas and that's all the material I had Actually, I can go back to this Comparing lambdas and prox in Ruby. There's a class called prox lambdas are instances of prox but prox Also include non-lambda prox Which is kind of confusing in a pain, but they do behave differently. So if you return from a lambda It does not return from the method in which it lives You can see here Whereas if you return from a prox it does return from the method another thing is lambdas are much more strict in their argument checking They have Well, we see here we get an error if we give the one number of arguments to lambda, but not for the prox and I just want to show you one other thing This is a So I have a gem called trick bag and I've used some of these techniques in that It's a Ruby gem that has just a bag of kind of unrelated Utilities that I've found to be useful and wanted to put on the public Internet somewhere so I can get them from anywhere And that's where this collection access thing is defined. This is what It looked like to define that lambda that we used to access that stuff Although to be fair it's calling this method which is here So it's a little bit more, but one of the things I love about Ruby is you can do it a lot with a little bit of code So I guess that's it any questions comments. No Okay, well, thank you very much for your time