Are these functions exactly same? That is, are 1st and 2nd syntax just convenient shorthand for the last syntax? Or is there some theoretical or practical difference, and if so, what is it?
let f1 a b = a + b
let f2 a = (fun b -> a + b)
let f3 = (fun a -> (fun b -> a + b) )
They seem the same to me, f1 5, f2 5 and f3 5 seem to return identical value, for instance. Just checking I’m not making invalid assumption here. In other words, I hope a knowledge-based answer, not one saying “Yeah, I believe they are the same”.
Your assumption is correct, in this case, the functions are exactly the same.
You can see that by inspecting the generated IL code (as demonstrated by Craig) and you can also see that by looking at the type inferred by the F# compiler. In both cases, you’ll see
int -> int -> int. The F# language views that as a function that takesintand returnsint -> intbut it is actually compiled as a method with multiple arguments (for efficiency).If you write
funimmediately followinglet .. =then the compiler turns that into a standard function. However, you can write code that is a bit different if you do some computation before returning the function:Now the two functions are very different, because the second one prints “hi” when you give it just a single argument (and then it returns a function that you can call):
You can write the same code using
f1, but the first command will just create a new function and the second command will print “hi” and do the addition.In this case, the generated IL code for
f2will be different. It will be a function that returns a function (of typeFSharpFunc<int, int>). The type displayed by F# is also different – it will beint -> (int -> int)instead ofint -> int -> int. You can use values of these two types in exactly the same ways, but it hints you that the first one may do some effects when you give it a single argument.