Monday, September 28, 2009

F# under the covers V

Doing some more detail work looking at patterns to be statically analysed, it's inevitable that you'll unearth some interesting behaviours, and here's another crop.

The obvious sink method

actually stores the argument (of generic type a) in a local variable before returning -- Reflector tells us it looks like

where in general there is one such local assigned for every argument; whereas a C# void method that just swallows its arguments

really does nothing with them, and just returns.

More interesting is the case of exceptions. There being no concept of a bottom type (like Scala's Nothing), exceptions have to be handled with care by the compiler. Take the cases of two dead simple stub routines -- things that exist to satisfy the linker, but which haven't been written yet, and should fail if called.

The Reflector derived C# equivalents are

Rather than throwing an exception “returning” a type that is a subclass of anything, the operation that wraps the actual throwing, however achieved, sports a generic return type that matches the return type of the function -- and when we explicitly specify the return type, the generic operation is set to that specific type. Meaning, of course, that a branch of a match or an if that results in an explicit exception will still match the type of the other clauses.

This behaviour is unchanged in the Feb 2010 CTP (


Stephan said...

Hey Steve,

The local copies of the unused function arguments are compiler artefacts that only show up in debug mode. You won't see these if you compile with activated optimizations. Of course, with activated optimizations the F# compiler will also inline all calls to ignore (at least within the same compilation unit).

Best regards,

Steve Gilham said...

Understood that this is in debug builds -- as argued before, that's the one that wants the FxCop analysis (as you don't want the SuppressMessage baggage in your release builds).