2

The problem is not new in stackoverflow, but I am not able to comprehend the behavior of let binding with patterns and of the in keyword. My textbook prefers the uncommon function definition format:

let foo = fun x -> let f = (fun x y -> x +y ) in f x    

So that I translated in #light syntax:

let foo x =
    let f y =
        x + y
    f x

If I set foo 4 it returns me 8. Why? I cannot comprehend what actually happens inside the function, even with the elegant explications from here. Why 4 becomes argument for both x and y?

Community
  • 1
  • 1
Worice
  • 3,847
  • 3
  • 28
  • 49

2 Answers2

6

You are defining a function inside another function, your inner function f captures a value from the outer function, the value x which is used in x + y so x becomes 4.

Then you call the inner function f x passing x to y which is also 4.

Another way to view it, without taking in account the specific value 4, your inner function is let f y = x + y but it's always called with x so y becomes x, then your function becomes something like let f a = a + a.

The key thing to understand this is that a function can capture a value from the context, in this case x.

So this explains the behavior of your function using the light syntax but you might be wondering why it differs from the one-liner version. It's because the translation is wrong. Here's the right translation:

let foo x =
    let f x y = 
        x + y
    f x

And now if you call it with foo 4 it returns a function that expect the other parameter.

Gus
  • 25,839
  • 2
  • 51
  • 76
5

Say we call the function foo with 4.

let foo x =
    let f y =
        x + y
    f x

foo 4

We can replace foo 4 with the function foo replacing all the x with 4.

let f y =
    4 + y

f 4

Now we can replace f 4 with the function f with y := 4.

4 + 4

Which is obviously 8.

CodeMonkey
  • 4,067
  • 1
  • 31
  • 43