What Is Closure, Proc and Lambda?

1. Closure
Closure is block of code/function/method that has two properties:
- It can be passed around like an object (to be called later).
- It remembers the values of all the variables that were in scope when the function was created, then it is able to access those variables when it is called.

Proc & Lambda are closure.

2. Proc (Procedure)
Proc is a closure and an object that can be bound to a variable and reused.

default proc
1
2
p = Proc.new { puts "Hello Rubyist" }
p.call # prints Hello Rubyist
proc with parameter
1
2
p = Proc.new { |a, b| puts "x: #{a}, y: #{b}" }
p.call(1, 2) # prints x: 1, y: 2
proc as closure
1
2
3
4
5
6
def proc_maker(arg)
  Proc.new { |a| a + arg }
end

p = proc_maker(10)
p.call(25) # return => 35
proc as closure
1
2
3
4
5
6
def to_do(p)
  p.call
end

p = Proc.new { puts "proc" }
to_do(p) # prints proc
proc as closure
1
2
3
4
5
6
7
8
9
10
11
12
def to_do(proc1, proc2)
  proc1.call
  proc2.call
end

a = Proc.new { puts "first proc" }
b = Proc.new { puts "second proc" }
to_do(a, b)

# prints
# first proc
# second proc

3. Lambda
Lambdas are a more strict form of Proc, something like:
- Lambda are more strict with regard to argument checking.
- Lambdas can return a value with the return keyword.

default lambda
1
2
l = lambda { puts "Hello Rubyist" }
l.call # prints "Hello Rubyist"
lambda with parameter
1
2
l = lambda { |a, b| puts "x: #{a}, y: #{b}" }
l.call(1, 2) # prints x: 1, y: 2
lambda as closure
1
2
3
4
5
6
def lambda_maker(arg)
  lambda { |a| a + arg }
end

l = lambda_maker(10)
l.call(25) # return 35
lambda as closure
1
2
3
4
5
6
def to_do(l)
  l.call
end

l = lambda { puts "lambda" }
to_do(l) # prints lambda
lambda as closure
1
2
3
4
5
6
7
8
9
10
11
12
def to_do(lambda1, lambda2)
  lambda1.call
  lambda2.call
end

a = lambda { puts "first proc" }
b = lambda { puts "second proc" }
to_do(a,b)

# prints
# first proc
# second proc