I recently wrote up some articles on how one might use currying, partial application and function composition along with C# and delegates to produce the factorial function from two higher-order functions. The result of this labor is below.
That code is a truly magnificent beast. While it's academically interesting to torture delegates like this, it isn't all that fruitful when the language (i.e. C#, VB) doesn't really support these shenanigans. Try that in some production code and see how quickly you lose your development job.
As an exercise, here's how I might build factorial using the same techniques in F#:
The first thing I should point out is that no delegates are used in this sample. F# natively supports functions as values so it's unnecessary to create delegates for them (and no, it doesn't create delegates under the covers). Secondly, functions are automatically curried in F#. You can declare functions so that they aren't curried, but that's really only useful if you're writing code that should be callable from other .NET languages. And finally, F# provides an operator (>>) for function composition.
To be fair, I should point out that the above implementation is pretty naive. It's not necessary to use function composition. This will suffice:
If compiled with fsc.exe, that code will print the following to the console:
That's great, but what if I try to calculate the factorial of 1000?
Hmmm... what's going on here? Well, it turns out that the F# compiler inferred the type of "factorial" to be:
"int" maps to the standard .NET type, System.Int32, so this factorial function expects an Int32 and returns an Int32. However, Int32 isn't actually large enough to hold the factorial of 1000. This is a job for F#'s "bigint" type. "bigint" maps to the Microsoft.FSharp.Math.Types.BigInt type which can represent arbitrarily large integer values. With a few minor modifications, the factorial function can use "bigint," and the factorial of 1000 can be properly calculated.
Now, the F# compiler infers the type of "factorial" to be:
And what does that program print to the console?
Awesome.
One last point: writing factorial in F# is completely unnecessary. It already exists.
Page rendered at Saturday, October 11, 2008 1:45:19 AM (Eastern Standard Time, UTC-05:00)