# Applications of Lambda in Ruby

### Intro

When I stumbled upon lambda for the first time in some other Ruby book, my first thought was like 'Hm, interesting thing, but why should I ever use it?'.

Wikipedia defines lambda as a not bound anonymous function and gives some use cases as to when lambdas are used in programming.

There are a lot of articles about the differences between Proc, Block and Lambda in Ruby, but none of them (at least those I read) answered my question.

It took time before I realized that it's, in fact, a nice-to-have tool, which one can use to better express ideas and even optimize code.

### Code Clarification

Let's have a look at the following code.

``````
a = (1..10).to_a

#lets double it

a = a.map { |x| x*2 }

``````

But is the example really clear? What if the block provided is a bit more complicated?

``````
rs = (1..10).to_a

areas = rs.map { |r| Math::PI * r**2 }

``````

It is still easy to read, but takes a little more effort to understand: we have to keep in mind that we have an array of some values

and we map it on some procedure that calulates power of 2 of its only argument and then multiplies it by PI. This procedure looks like a circle area calculation

algorithm. So `areas` is the array of circle areas calculated based on the array of radiuses defined above. Too much effort for a single line of code, huh?

To make it clear we can use lambda.

``````
calculate_circle_area = -> r { Math::PI * r**2 }

areas = rs.map(&calculate_circle_area)

``````

Now, we first get knowledge about how to calculate the area of a circle and only then we map an array with the defined procedure. Also we

can use our lambda as many times as we want.

### Sorting

``````
a = (1..100).to_a.shuffle

a.sort

``````

It is simple enough, but Ruby is a very expressive language, so why not make our code clearer?

Enumerable#sort has zero arguments, but accepts optional code block which defines the way sorting is performed. However, if

we try to pass it a lambda - interpretor explodes with Exception!

``````
# let us do the same as above, but with lambda

in_ascending_order = -> left, right { left <=> right }

a.sort in_ascending_order

#=> ArgumentError: wrong number of arguments (given 1, expected 0)

``````

Ok, it passes lambda as argument, which is erroneous. Of course, we have to pass it as code block! We can easily convert

lambda to block with unary & operator which just sends it a :to_proc message. Let's try again.

``````
a.sort &in_ascending_order

``````

And it worked as planned, more so: we gave our code expressiveness worth of Ruby.

### Currying

This one is rather tricky. As we already know, lambdas can take arguments. With currying we can provide it with only some of them.

``````
sum = -> a, b { a + b }

``````

Now we have `add_three` lambda which takes only one argument and adds it to 3. We can use it with Enumerable#map:

``````
a = [*1..100]

``````

If there are not enough arguments supplied to `curry` function it returns new lambda with bound variables. Otherwise it just evaluates lambda with given parameters.

So we apply curried `sum` with bound `3` to array with `map`.

### Higher-order functions

Such functions are just functions that take other functions (or Ruby code blocks) as arguments. And most of us have already used or at least seen them in code.

The most frequently used ones are in Enumerable. #map, #select, #reduce and others are all higher-order functions. So, let’s lets make our own!

``````
class Example

def initialize(argument)

@value = argument

end

def apply(lambda)

lambda.(@value)

end

end

double = -> x { x * 2 }

Example.new(10).apply double

``````

### Closures

Lambda in Ruby can bind variables local to the context in which it was defined. Let me clarify this with an example.

``````
def t(argument)

-> { puts argument }

end

t('one to bind them all').call

``````

So, we defined method #t with arity of 1, which returns a lambda which, in turn, prints an argument to \$stdout. Now we can

try something more useful.

``````
def compare_with(threshold)

-> x { x > threshold }

end

# Array generation from Range using splat operator

a = [*1..100]

greater_than_10 = compare_with(10)

a.select &greater_than_10

``````

Let's be more real and apply lambda to a more sophisticated case.

``````
class CarBuilder

def initialize

@car = Struct.new(:body, :wheels, :engine).new

end

sleep 1

car.body = body

end

sleep 2

car.wheels = wheels

end

sleep 3

car.engine = engine

end

def get_result

car

end

private

end

``````

Think of #sleep method as of some IO. To help ourselves build car faster with Threads here is complementary class.

``````
class Pipeline

def initialize

@pipeline = []

end

def <<(callable, *args)

end

def sync

@pipeline.each(&:join)

clear

end

def clear

@pipeline.each(&:kill)

@pipeline = []

end

end

``````

And now we can build our car in parallel Threads with lambdas.

``````
c = CarBuilder.new

p = Pipeline.new

p << -> { c.add_engine("2,5l v8") }

p << -> { c.add_wheels("18'") }

p << -> { c.add_body("sedan") }

p.sync

puts c.get_result

``````

### Gotcha!

Closures may be dangerous. Have a look at this code.

``````
i = 0

a = [*1..10].map do |x|

i = x

-> { i }

end

``````

Lambda will capture `i` by reference - not value. And if you now run this:

``````
a.binding.local_variable_get(:i)

a.binding.local_variable_get(:i)

``````

… the results will be same! So, watch your namespace.

This concludes some applications of lambda I found useful. Happy coding!

Do you have a project for us?Get a free quote