In which I delve into F# for the first time…
I eventually got around to installing VS2010 yesterday, and decided to start with something entirely new to me, namely F#.
Firstly, I spent an hour or so watching the three lectures given by Dr Don Syme on Channel 9. The presentation is extremely quick-paced, but gives a good feel for the language.
Then, I spent half and hour playing around before I decided it was time for a real-world example. I picked a present value function to translate… It’s a simple enough bit of code in C#.
public enum PaymentDue { AtEndOfPeriod, AtStartOfperiod, } public static class Financial { public static double PresentValue( double ratePerPeriod, int numberOfPeriods, double paymentPerPeriod, double futureValue, PaymentDue paymentDue) { double compoundRate = Math.Pow(1 + ratePerPeriod, numberOfPeriods); double additionalRate = (paymentDue == PaymentDue.AtEndOfPeriod) ? 1 : (1 + ratePerPeriod); return (-paymentPerPeriod * additionalRate * ((compoundRate - 1) / ratePerPeriod) - futureValue) / compoundRate; } public static double PresentValue( double ratePerPeriod, int numberOfPeriods, double paymentPerPeriod) { return PresentValue(ratePerPeriod, numberOfPeriods, paymentPerPeriod, 0, PaymentDue.AtEndOfPeriod); } }
So how easy would that be in F#? It turns out that it’s pretty easy… at least to start with.
Here’s what I came up with…
type PaymentDue = | AtEndOfPeriod | AtStartOfPeriod let PresentValue(ratePerPeriod:float, numberOfPeriods:int, paymentPerPeriod:float, futureValue:float, paymentDue:PaymentDue) = let compoundRate = (1.0 + ratePerPeriod) ** (float)numberOfPeriods let additionalRate = match paymentDue with | PaymentDue.AtEndOfPeriod -> 1.0 | PaymentDue.AtStartOfPeriod -> 1.0 + ratePerPeriod (-paymentPerPeriod * additionalRate * ((compoundRate - 1.0) / ratePerPeriod) - futureValue) / compoundRate System.Console.WriteLine(PresentValue(0.05, 24, 1000.0, 0.0, PaymentDue.AtEndOfPeriod))
Now F# uses type-inference: so it’s not actually necessary to specify types on the PresentValue function signature. However, it still feels safer to do so. Similarly it’s not necessary to fully qualify the enumerated constant AtEndOfPeriod.
I haven’t looked to see how easy (or possible) it is to overload functions in F#. And I haven’t attempted to encapsulate the function in a containing Financial type either. I’ll leave that for another day.
So, all together a quite positive experience. Now, what’s next…