06 Jan


Another mea culpa observed by André van Meulebrouck; when dealing with casting I am in error and not as consistent in defining and describing it as I perhaps should be – one of the many perils of proof-reading your own material! For example, on page 338 of Volume I, I incorrectly associate boxing with down-casting where it should be up-casting!

Let’s limit our scope of consideration to .NET Class Hierarchies – in this respect I mean the way in which object inheritance is depicted in the MSDN documentation. For example, the WPF FrameworkElement has the following inheritance hierarchy (in part – for the original click here)…

Inheritance Hierarchy Sample

This could also be “visualised” as a simplistic (asexual) genealogical family tree where the “originator”, the .NET System.Object, is at the top of the stack. If you want to see the “complete” family tree for WPF and .NET 4.5 have a look at this StackOverflow question – WPF 4 and .NET 4.5 class hierarchy poster.

When up-casting from the FrameworkElement one regresses through the ancestors – you go “up the family tree” to some point that may or may not terminate with the originator – the Object. Conversely, when down-casting, you go down through the descendants of FrameworkElement.

The up-cast operator :> is “static” – the compiler will let you know when you’re writing your code if there’s an error in your casting logic. Of course, you can always cast up the inheritance hierarchy to an Object but you cannot, for example, try…

let form = new Form()
let b5 = form :> TextBox

In this case the compiler knows, at design-time, that there is an error in your casting logic – TextBox is not an ancestor of Form in its inheritance hierarchy and the statement will be shown with a red squiggly – however, form :> obj will always “work” since, for .NET, Object is always at the root of the family tree. Consequently, when up-casting with :>, as long as your code compiles you won’t get a run-time type exception.

For down-casting, André proposes the mnemonic: The downcast operator :?> is downcast because it is sad that it can’t know at compile time whether the cast will work! Fair enough – I guess this is based upon emoticons – a “language” I am unfamiliar with!

06 Jan

Fold versus Reduce

André van Meulebrouck makes the comment that, in Volume I, there are instances where I should be using List.Reduce as opposed to List.Fold. I don’t deny that this is the case; firstly, let’s clarify the difference between the two functions as used for F# collections in general…

Fold requires a “starting value” into which elements are to be collated; the starting value can be any primitive F# type – I often use a string. Conversely, Reduce does not require a starting value consequently, the type used in the Reduce anonymous function must be of the same type as expressed by the collection (elements) one is folding.

I would be hard-pressed to quantify general processing performance differences between Fold and Reduce but I suspect that Reduce is faster since the accumulator and element value types must, by definition, all have the same primitive type. I guess the “general rule” about making a choice between the two is that if your accumulator is going to be the same primitive type as your collection elements then use Reduce – otherwise, use Fold since there will be some implicit casting involved – even if only in using the string representation (ToString()) of a collection element to enable the accumulator to “work”.

Contact Form

Contact Form

You may use this form to send me an email…
Click on the panel tab or elsewhere on the screen to close this panel.