Lambda composition

313 views

What is the return value of the following Ruby code?

dec = ->(n) {n-1}
inc = ->(n) {n+1}
dbl = ->(n) {n*2}

(dec << dbl >> dbl << inc).call(0) # => ???

The correct answer is

-3

It raises SyntaxError

3

2

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

Explanation

In CompSci, the notion of Function Composition refers to the act of combining multiple functions to build more complicated ones.

In Ruby, this notion is represented by the Proc#<< and Proc#>> methods

increment = proc {|x| x + 1}
double    = proc {|x| x * 2}

(double << increment).call(5) # => 12

Let’s detail step-by-step what occurred in the previous example

increment = proc {|x| x + 1}
double    = proc {|x| x * 2}

x = 5

x = increment.call(x) # => 5 + 1 = 6
double.call(x)        # => 6 * 2 = 12

As we use the left-shift operator, the right-hand proc (increment) is executed first and the result of this proc call is passed as an argument of the left-hand proc call (double).

The mechanism is the same for the right-shift operator except that the left-hand proc is executed first.

Let’s detail step-by-step what occurred the code example of the quiz

dec = ->(n) {n-1}
inc = ->(n) {n+1}
dbl = ->(n) {n*2}

(dec << dbl >> dbl << inc).call(0) # => 2

The right-hand procs are executed first from right to left.
Then the left-hand procs are executed from left to to right.

dec = ->(n) {n-1}
inc = ->(n) {n+1}
dbl = ->(n) {n*2}

x = 0

x = inc.call(x) # => 0 + 1 = 1
x = dbl.call(x) # => 1 * 2 = 2
x = dec.call(x) # => 2 - 1 = 1
x = dbl.call(x) # => 1 * 2 = 2

(dec << dbl >> dbl << inc).call(0) # => 2

Let's change the procs a little bit to show you the order of execution

one   = ->(n) {puts 1}
two   = ->(n) {puts 2}
three = ->(n) {puts 3}
four  = ->(n) {puts 4}

(three << two >> four << one).call(nil)

Output

1
2
3
4

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

RubyCademy ©