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, March 13, 2010 3:04:32 AM (Pacific Standard Time, UTC-08:00)
If you're interested in learning F#, this is the most comprehensive book available. The text is well written and the examples are instructive. And after all, the author is the inventor of F#.
Because this book provides source code in Standard ML, it's a fantastic resource for learning F#. One bit of warning: this book does not teach classic data structures. While structures such as binomial heaps and red-black trees are presented, it is assumed that the reader already knows and understands them.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.