From C# to F# – Part 2
Last time I posted I explained that F# compiler simply evaluates function calls from left to right. Since that tends to be a sticking point for most people coming from imperative programming languages here’s an under the hood look.
Remember, we had a function that looked like this:
let add x y = x + y
This function is very simple, here is the C# equivalent:
int add (int x, int y) {
return x + y;
}
But the function call is more complex. If you remember, the call was:
let a = add 1 2
Now, the .NET library has the following delegates declared:
delegate TResult Func<TResult> (); delegate TResult Func<T, TResult>(T arg); delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
Also, the F# library has the following functions:
Func<T2, TResult> Evaluate<T1 ,T2, TResult> (this Func<T1, T2, TResult> f, T1 arg1) {
return arg2 => f (arg1, arg2);
}
TResult Evaluate<T, TResult> (this Func<T, TResult> f, T arg) {
return f (arg);
}
So when the compiler reads the line:
let a = add 1 2
it simply reads the function body left to right and strings the Evaluate statements, producing the code that is the equivalent of the following C# code:
var a = new Func<int,int,int> (add).Evaluate(1).Evaluate(2);
(Of course there are optimizations so this case will be compiled to the same straightforward IL as the C# code, but the main point is that at the basic level it’s just an evaluation left-to-right with calls to Evaluate.)
Now here’s the cool thing about F#: You can also call the function add with just one parameter, and it will, as you can see above, produce a new function that takes an additional parameter before returning the result:
let addone = add 1 let b = addone 2
This property of F# and other functional languages is called currying.
Now currying is mondo cool and you’ll be using it a lot when programming in F#, but it also leads us to an important point about type signatures:
Say you have a function that takes an integer and returns an integer:
let square x = x * x
If you look at the type of the function square (hover over it until the intellisense tooltip pops up), F# will report it as int –> int. That means that it’s a function that takes an integer and produces an integer.
But if you hover over the definition of the function add:
let add x y = x + y
Visual Studio will report the type of add to be int –> int –> int. What the … ?
It’s simple. Even though you think of a function add as a function that takes two integers and returns an integer, the F# compiler interprets it as a function that takes one integer and returns another function that takes one integer and returns an integer.
In other words, the F# compiler views add as int –> (int –> int), but then simply removes the unnecessary parenthesis (1 + (1 + 1) == 1 + 1 + 1) and presents you with the endless string of arrows like this int –> int –> int.
As a C# programmer, you might find it most comfortable to take a soup that looks like this:
int –> double –> string –> bool
and think about it like this:
int, double, string –> bool
e.g. a function that takes an int, a double and a string and returns a bool.

30. October 2009 at 09:10
[...] Part 2 [...]
30. October 2009 at 11:41
> This property of F# and other functional languages is called currying.
I disagree. This property is called partial application. Or curried functions, maybe.
Currying is the transformation from an n-ary function (or more precisely a function taking an n-tuple as its argument) into a function taking 1 argument and returning chain of n-1 functions. (in haskell-types, curry :: ((a, b) -> c) -> a -> b -> c), so “this property” definitely isn’t called currying.
30. October 2009 at 12:00
“Now currying is mondo cool and you’ll be using it a lot when programming in F#”
Have you ever been given an application to update where the original developer had used an egregious amount of currying? It is possible to be driven quite nuts developing your own flow analysis code just to figure out what was going on. I’m not sure I would ever even consider using F# if its one ‘cool’ aspect is making currying easier.
30. October 2009 at 12:05
masklinn, you’re completely right. I was playing it loose with terminology.
30. October 2009 at 12:10
Michael,
Yeah, currying taken too far is a complete brain-fuck. I remember once trying to shorten a short program as much as possible just for fun (using operators and currying) and then suffering the pain of having to explain what the code does to someone else a week later.
Dejan
31. October 2009 at 12:34
[...] my last post leaves me with a bunch of things that deserve further explanation and further spelunking through [...]