How do the lambda functions in this solution actually work?

277 views Asked by At

I'm trying to understand a solution to a problem that involves lambda functions, but I can't get just one part through my head.

Problem Statement

seven(times(five())) # must return 35
four(plus(nine())) # must return 13
eight(minus(three())) # must return 5
six(divided_by(two())) # must return 3

Requirements:

  1. There must be a function for each number from 0 ("zero") to 9 ("nine")
  2. There must be a function for each of the following mathematical operations: plus, minus, times, dividedBy (divided_by in Ruby and Python)
  3. Each calculation consist of exactly one operation and two numbers
  4. The most outer function represents the left operand, the most inner function represents the right operand
  5. Division should be integer division. For example, this should return 2, not 2.666666...:

Solution

def zero(f = None): return 0 if not f else f(0)
def one(f = None): return 1 if not f else f(1)
def two(f = None): return 2 if not f else f(2)
def three(f = None): return 3 if not f else f(3)
def four(f = None): return 4 if not f else f(4)
def five(f = None): return 5 if not f else f(5)
def six(f = None): return 6 if not f else f(6)
def seven(f = None): return 7 if not f else f(7)
def eight(f = None): return 8 if not f else f(8)
def nine(f = None): return 9 if not f else f(9)

def plus(y): return lambda x: x+y
def minus(y): return lambda x: x-y
def times(y): return lambda  x: x*y
def divided_by(y): return lambda  x: x/y

My Issue

In def plus(y): return lambda x: x+y, how are both arguments passed to this function? I understand that it has something to do with "closure", but I'm not able to find any documentation that helps me understand it in this context.

For example: three(plus(one())) expands to return 3 if not plus() else plus(3).

Then, plus(3) expands to return lambda x: x + 3. Where does that x get its value from?

1

There are 1 answers

2
BrokenBenchmark On BEST ANSWER

In def plus(y): return lambda x: x+y, how are both arguments passed to this function?

It doesn't -- or at least, plus() doesn't pass both arguments into the lambda function. plus(3) returns lambda x: x + 3 -- a function that takes in one argument and increments its argument by 3. This process is known as currying.

To address your example, three(plus(one())):

  • one() returns 1.
  • plus(one()) becomes plus(1) and returns lambda x: x + 1.
  • three(plus(one()) becomes three(lambda x: x + 1). three() calls the lambda function passed in with an argument of 3 and returns the resulting value. This gives a final result of 4.