Intro
In this post I'll be getting into some of the key parts of Ruby, lambdas and procs. I'll also get into the main differences between them, and how to use either properly.
What are Lambdas?
Lambdas, what the hell is that?
This might be difficult to grasp, and I'm also not the best at explaining, but lambdas are basically small scale functions, that behave like methods. Kind of.
I don't get it.
Okay, a lambda is a block of code that is assigned to a variable. Lambdas require all input/parameters functions do to work, so without them Ruby will return an error. Lambdas are assigned(usually) to a variable, this makes them executable only when the variables value is called. Here's an example:
squared = lambda {|x| x**2}# or {|x| x*x}
[1, 2, 3, 4, 7].map(&squared)
#=> [1, 4, 9, 16, 49]
What happened?
Basically, I used the & to reference squared
and map called it on each item of the list to create a new list. Its values are [1, 4, 9, 16, 49]
.
That's pretty much the basics for writing lambdas, but, of course there's more. We'll get into them a bit later.
Procs
NO!
Procs are an essential part of Ruby. Senior and Junior Ruby developers alike should know how to use Procs. Procs are from the builtin "Proc" class in Ruby. They're blocks of code assigned to a variable.
How do I use a Proc?
Simple here's an example:
myProc = Proc.new {=begin Random block to later be executed =end}
Okay that doesn't look too confusing. But what's the difference between a Proc and a Lambda, other than syntax.
It's actually on the surface, there isn't one. They can be used to do the exact same job almost all the time. There's one small difference that I'd like to note though. Lambdas, which mind you are still nameless functions, aren't evaluated until they're called. But Procs are a class type so they're evaluated immediately. Let's use a simple example so you understand what that means for your code.
With a Proc
def myFunc()
myBlock = Proc.new {return "Hello"}
return "#{myBlock} World!"
end
With a Lambda
def myFunc()
myBlock = lambda {return "Hello"}
return "#{myBlock} World!"
end
If you haven't already noticed with the Proc the intended output never got returned. Since it was evaluated before it was called returning "Hello" ended the function, meaning the next line was never called. With the lambda that doesn't happen because Ruby skips it until it's later called by the return statement at the end of the function. Giving us "Hello World!", the intended output. This is kind of contrived but it's a difference worth pointing out. So having a return statement or any hard coded out put in a Proc is a bad idea.
That's that folks. 😄!!!
The part about procs being evaluated immediately is wrong. Procs, just like lambdas, are evaluated only when you call them; or rather, when you send them the
:call
signal.The difference is that, simpy by design, a proc can return from the method that calls it; that is, when function F calls a proc P and P returns, not only P ends there, but F also finishes. You could say P returns on behalf of F.
Lambdas, on the other hand, can only return from themselves, not from the function that called them. If a function F calls a lambda Λ, and Λ returns, F will continue where it called Λ as if it had been any other method call.
The other big difference is that lambdas, just like functions, have an arity and passing them the wrong number of arguments will cause an error. Procs, just like blocks, treat missing arguments as
nil
and discard extra arguments.EDIT: Ironically, Ruby might be the wrong place to start when you want to learn about lambdas though. I would recommend trying out some other language that relies more heavily on anonymous functions (Lua being my personal favourite) to get a better feeling for the whole concept. Fromthere, you can go back to ruby and it will make much more sense.