Procs and Lambdas
Tags: ruby, beginners, programming
Published: 2020-04-27 17:40:02

---
title: Procs and Lambdas
published: true
description: 
tags: ruby, beginners, programming
---
Today I was refreshing my knowledge and learning something new about **proc** and **lambda** in Ruby and wanted to share some info about it that, hopefully, might be useful for somebody else.

In the [previous post](https://dev.to/marynanogtieva/ruby-blocks-3cdf) we discussed that almost everything is an object in Ruby except blocks.
Block in Ruby is a very useful feature that helps to remove some repetition in the code and perform various operations on data structures dynamically.

However, sometimes(not too often) we might need to have a way to store a block of code into a variable, which is not possible with regular Blocks in Ruby:

```ruby
# This will not work and an exception will be thrown
a = { puts "Hello" }  # Ruby expects a hash here between curly braces

# syntax error, unexpected keyword_do_block
b = do
  puts "Hello"
end
```

## Enter lambdas and procs :sparkles:

Lambda and proc are wrappers around a block that allow us to store a block of code into a variable and use it later. This variable will be an object - an instance of the [Proc](https://ruby-doc.org/core-2.7.1/Proc.html) class.

After a proc is created it can be later passed as an argument to a method.

```ruby
names = ['Anna', 'Alex', 'Hellie', 'Martin']
proc_name = Proc.new { |name| name.start_with?('A') }
selected_names = names.select(&proc_name)
```
In the example above we can see only two names printed out

```
["Anna", "Alex"]
```

### Creating lambda and proc

Proc class has two flavors: `proc`s and `lambda`s. We will discuss their differences in a moment but first let's review how we can create them. There are few ways both to create and call `proc`s and `lambda`s:

```ruby
proc1 = Proc.new { puts "I'm proc1" }
##<Proc:0x00007fce97948b40@(irb):117>
proc2 = proc { puts "I'm proc2" }
##<Proc:0x00007fce9793a180@(irb):118>

lambda1 = lambda { puts "I'm lambda1" }
##<Proc:0x00007fce9792a870@(irb):120 (lambda)>
lambda2 = -> { puts "I'm lambda2" }
##<Proc:0x00007fce9791bbb8@(irb):121 (lambda)>
```

Stabby lambda `->` is a new syntax for creating lambdas and is used more often than `lambda` keyword.

### Calling lambda and proc

There are many ways to call both lambda and proc. I personally prefer `.call()` and `.()` syntax.

```

proc1.call()
lambda1.call()
I'm proc1
I'm lambda1


proc1.()
lambda1.()
I'm proc1
I'm lambda1

proc1.[]
lambda1.[]
I'm proc1
I'm lambda1

proc1.===
lambda1.===
I'm proc1
I'm lambda1
```

### Difference between lambda and proc

Both lambda and proc are similar on the surface but actually behave quite differently. They are similar in a way that they are instances of the same `Proc` class.

```ruby
irb(main):126:0> proc1.class
Proc < Object

irb(main):127:0> lambda1.class
Proc < Object
```

But one should not be confused by that fact. We should take a closer look at `lambda` and `proc`:

- **`proc` is not strict with the number of arguments passed**

```ruby
number_of_students = Proc.new do |number|
 if number
  puts number
 else
  puts "no students"
 end
end

# prints 20
number_of_students.call(20)

# prints "no students"
number_of_students.call()
```

- **`lambda` can scold you in case you pass the wrong number of arguments.**

```ruby
number_of_students2 = ->(number) do
 if number
  puts number
 else
  puts "no students"
 end
end

# prints 10
number_of_students2.call(10)

# throws an exception: ArgumentError (wrong number of arguments (given 0, expected 1))
number_of_students2.call()
```

- **Keyword `return` has a different behavior:**
- **“return” in lambda behaves like “return” in a method** - you call a method from another method, get a return value, and carry on with the code below it.
- **"return" in proc behaves the same way as in a block**. If a `proc` with `return` keyword is called inside a method, then code specified below `proc.call()` will not be executed. The method will return a value that is being returned by the `proc`.
Note,  if you declare `proc` with `return` in the top context and then pass it to a method as an argument, you will get an exception `LocalJumpError: unexpected return` because we are not allowed to return from top-level context.

Let's look at some examples.

- When a lambda is declared outside of the method(passed to the method as an argument) and when another lambda declared inside a method, we will see all four lines printed out.

```ruby
def my_lambda(lambda_obj)
  internal_lambda = -> { return "in internal lambda" }

  puts "before lambda"
  puts internal_lambda.call
  puts lambda_obj.call
  puts "after lambda"
end

lambda_obj = -> { return "in outside lambda" }
my_lambda(lambda_obj)
```

Output:
```
before lambda
in internal lambda
in outside lambda
after lambda
```

 - When a proc is declared outside the method in a top-level scope an error will be thrown.

```ruby
outside_proc = Proc.new { return "From outside proc" }

def my_proc(proc_obj)
  puts "before proc"
  puts proc_obj.call()
  puts "after_proc"
end
   
my_proc(outside_proc)
```
 
Output:
```
before proc
LocalJumpError: unexpected return
	from (irb):98:in `block in irb_binding'
	from (irb):102:in `my_proc'
```

 - When proc is declared inside the method, it will be binded to the method scope, and lines that come after calling proc will not be printed out.

```ruby
def my_proc
  proc_obj = Proc.new { return "From inside proc" }

  puts "before proc"
  puts proc_obj.call()

  # this will not be printed out
  puts "after_proc"
end

my_proc
```

Output:
```
before proc
"From inside proc"
```

### Ruby has functional programming features?
  Ruby is one of the purest object-oriented languages but it is spiced up with functional programming flavors. I have some experience with JavaScript and my examples will reference this language for comparison purposes.

- [Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures).
  In JavaScript closure allows the inner function to have access to the lexical scope of the outer function. 
Procs in Ruby are also bonded to the variable and have access to the context/scope where that variable was declared. Let's see an example:

```ruby
salary = 1000
bonus  = 500

salary_and_bonus = Proc.new { puts "#{salary + bonus}" }

def print_salary_with_bonus(my_proc)
  bonus = 700
  my_proc.call
end
```

Will the result of calling `#print_salary_with_bonus` method be a `1500` or `1700` ?

```
irb(main):116:0> print_salary_with_bonus(salary_and_bonus)
1500
```

Because we declared our `salary_and_bonus` proc in the outer scope it had access (remembered) to everything else declared in the same context. Therefore, our output printed `1500`.

- Composition. [>> operator in Ruby](https://ruby-doc.org/core-2.7.1/Proc.html#method-i-3E-3E). 
A composition is an assembly of multiple functions combined together into one function to perform multiple operations on one piece of data.
Basically, composition allows us to combine two or more functions into one function. 

`Proc#>>` was introduced in Ruby `2.6` and it allows us to perform some fun tasks. Let's imagine that we went to an online store and decided to purchase one item from there.
Here is how we would calculate its final price by using a composition:

```ruby
WHOLESALE_PRICE = 400

base_price     = ->(price) { WHOLESALE_PRICE + price }
handling_price = ->(price) { price + price * 0.1 }
total_tax      = -> (price) { price + price * 0.13 }

calculate_final_price = base_price >> handling_price >> total_tax
final_price           = calculate_final_price.call(100)

# final price => 621.5
```
Interestingly,  `Proc#>>` in ruby switches the order of a function call comparing to composition in Haskel or Math.
Usually, when we use a composition the order of data processing goes from right to left `f(g(x))` - first we process `x` and then `g`.

With `Proc#>>` we process data from left to right. However, `Proc#<<` allows us to process data the same way as it's done in functional programming :slightly_smiling_face: . I suggest checking this [blog](https://blog.stanko.io/function-composition-ruby-8f91aea21e5f) for more details on that.

[Here](https://thoughtbot.com/blog/proc-composition-in-ruby) is a nice article to learn more about composition in Ruby in detail.

- Function currying.
If you learned any functional programming you probably encountered `currying` paradigm before. 

With the help of currying, you can take a function with 2 arguments, call this function with one argument. This is called a partial application. Then call the partial application with the final argument to complete the function and evaluate the result.

If you are wondering how currying in ruby can be useful "Applying Higher-order Functions: Partial Application and Currying" part of this [article](https://www.sitepoint.com/functional-programming-techniques-with-ruby-part-ii/) would be a very good read to get more knowledge on that.

Let's try to take the previous example of an item's price calculation and try to use [Proc#curry](https://ruby-doc.org/core-2.6.1/Proc.html#method-i-curry) for that purpose:

```ruby
WHOLESALE_PRICE = 400

calculate_price = ->(method, price, additional_cost) do
  price.send(method, additional_cost)
end

add = calculate_price.curry.call(:+)

base_price = add.(WHOLESALE_PRICE, 100)
# => 500
handling_price = add.(base_price, base_price * 0.1)
# => 550.0

tax = handling_price * 0.13
final_price_with_tax = add.(handling_price, tax)
# => 621.5
```

Thanks for reading, I hope you found this information useful :slightly_smiling_face: