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 (126.96.36.199).