1

When I try to print and see what each function does, I'm able to call only the h function. All others return functions.

Also, can anybody tell me why this code prints 13 and what is happening?

two_to_one = lambda g: (lambda y: g(y,y))`
one_to_two = lambda f: (lambda x, y: f(x) + f(y))
h = one_to_two(two_to_one(lambda x, y: x*y))
print(h(3,2))
4
  • Did you take a look at this? stackoverflow.com/questions/890128/… Commented Jan 21, 2018 at 6:54
  • yes, there are a lot of examples there, but I still can't how can the lambda use itself (like a recursion) - as happening in the first two rows. Commented Jan 21, 2018 at 7:07
  • Possible duplicate of Lambda inside lambda Commented Jan 21, 2018 at 7:10
  • I read it. did not get an answer from that. thank you Commented Jan 21, 2018 at 7:11

3 Answers 3

4

That was quite a mind bender!

So let's just break the logic bit by bit. We'll start from h, it is essentially

 h = lambda x, y : x*x + y*y
 h(3,2) # output is 13

Now, we'll be good programmers and look for repetition. x*x and y*y are essentially the same thing. Why not have a lambda that does that?

 a = lambda x: x*x
 h = lambda x,y: a(x) + a(y)
 h(3,2)

Good, but I want the caller to decide whether to do x*x or x**x or x+x. Everytime I do that I dont want to change a. So I instead pass a lambda to a with whatever operation I want to perform

# a is just a delegator now. It just calls the lambda that it is "initialized" with passing the values twice
a = lambda lambdaIAmPassing: (lambda someValue: lambdaIAmPassing(someValue, someValue))
# lets pass a multiplication lambda
mul_a = a(lambda x,y: x*y)
# lets pass a addition doing lambda
add_a = a(lambda x,y: x+y)
h = mul_a(3) + mul_a(2)
print h #output is 13
h = add_a(3) + add_a(2)
print h # output is 10

Is this clear? You would have realized now that a is in fact the lambda two_to_one in your question

Now the final step.Do you see any other repetition in the code? we are calling mul_a twice and add_a twice. So to avoid this we define a lambda that calls whatever function is passed to it twice - once per parameter - and adds up the values

# Lambda that adds up the result of the function call
lambda_adder = lambda f: (lambda value1, value2: f(value1) + f(value2))
"Initialize" this lambda with mul_a
h = lambda_adder(mul_a)
h(3,2) # output is 13

Hence we end up with the code in your question

Sign up to request clarification or add additional context in comments.

Comments

2
two_to_one = lambda g: (lambda y: g(y,y))

This equals a function which calls a function g, passing it two variables, both y. In this case, g is

lambda x, y: x*y

because that is the argument passed to two_to_one on the third line (h's assignment).


one_to_two = lambda f: (lambda x, y: f(x) + f(y))

This equals a function which returns the sum of two calls to the function f, passing the values x and y. In this case, f is the two_to_one function.


Breaking it down:

first = lambda x, y: x*y
second = lambda y: first(y,y)
third = lambda x, y: second(x) + second(y)

simplifies to:

second = lambda y: y * y
third = lambda x, y: second(x) + second(y)

simplifies to:

third = lambda x, y: x * x + y * y

So, what the code is doing is returning the sum of the squares of the arguments. In this case, they are 3 and 2.

3 * 3 + 2 * 2 = 13

9 + 4 = 13

Comments

0

I hope it will be relatively easy to follow.

two_to_one = lambda g: (lambda y: g(y,y))

two_to_one is a function, with an input of a function (g: a function with an input of two parameters (as seen in g(y,y)), and output of a function (with 1 input y, and output of g(y,y)). Meaning it is a function of functions. So when giving two_to_one a two parameter function g, you get back a function, that takes 1 number and outputs g(y,y). e.g:

two_to_one(lambda x,y:x+y)(3)
6

We gave two_to_one a function that gets two numbers and output their sum, lambda x,y:x+y, and we got back a function that takes 1 number and output its sum with itself two_to_one(lambda x,y:x+y). So with an input of 3 it outputs 6.

Second line is similiar:

one_to_two = lambda f: (lambda x, y: f(x) + f(y))

Take a function f (of 1 parameter - due to f(x)), and give back a function, that gets two parameters (numbers probably) x,y and outputs f(x) + f(y).

Now, for the 13 output - working from inner to outer:

h = one_to_two(two_to_one(lambda x, y: x*y))

lambda x, y: x*y two parameter input - output of multiplication. This is the input of two_to_one so (remember what was written earlier) two_to_one(lambda x, y: x*y) is a function that gets 1 number, and returns it squared. And finally, feeding this function to one_to_two gives a function that gets two numbers (those x,y frim before) and returns their sum of squares.

In total h(3,2) gives 3**2+2**2=13.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.