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

Thursday, September 24, 2009

Film festival -- after action

  • From Russia with Love... -- filling a gap in my viewing with this relic of a more innocent age : "Mr Bond, this suitcase contains a throwing knife, a tear-gas grenade, a folding sniper rifle, twenty rounds for same and 50 gold sovereigns. Your mission is to get this onto your flight to Istanbul."; and cut to new scene rather than spending many tedious minutes in fumblings and gaspings.

    So, even though Bond is the fairly archetypical faceless and sketchy eroge self-insert protagonist, Connery pulls it off with style, and fires his Checkov guns with panache.

  • Our Hospitality -- slapstick and Keaton playing with trains. As time goes by, I start to wonder how the mix of drama and knockabout was intended to be received by the contemporary audience.

  • Vampyr -- An interesting contrast to the previous year's Dracula. That was a narrative film with rubber bats.

    This, by contrast, is a pure SFX movie, making much more effective use of available technology. Alas, like all SFX movies, the trickery cannot completely hide the weakness of the other elements -- there is all the narrative coherence of a dream, and only sometimes, the atmosphere of one, as we move from one little set piece to the next. Even the conclusion, with the ingenious demise of the enabler doctor comes out of nowhere -- Chekov's gun is never displayed here before use.

    Taken as a mood piece, quite effective -- would that modern SFX movies would use some of the quieter restraint like this!

  • Thirst -- For anyone wanting to see Park Chan-wook (Oldboy etc.)'s vampire movie, I'll spoil it for you -- the punchline is

    It's an over-long, rambling, jumble of a film. While it starts off promisingly, and seems to be going to invert and subvert genre clichés (a priest begging to be turned into a vampire; the vampire snacking happily from hospital supplies), after what seemed to be about to be the climax (and was probably only 60% of the way through the film) it then wanders off into an entirely different genre

    All the cinematographic style in the world could not save this train-wreck of a movie.

  • The Girl with the Dragon Tattoo -- After the above, I was in no mood to sit through 2.5 hours of Swedish cinema, so gave it a miss.

  • The Ipcress File -- I'd seen this nearly 40 years ago on TV in black and white, and remembered only a couple of fragments (the tape, the nail); so not only was the colour a welcome surprise, but so was the length and complexity of the lead in. Palmer -- for all his little pretentious quirks -- is so much more an accessible character than the adolescent fantasy that Bond represents. Well worth the rewatch (my festival pick)

  • Ghosted -- a German lesbian take on a Chinese style love/ghost story. Cleverly done with video intercut as well as outright flashback as we find out how everything unfolded. The brief sex scene was orders of magnitude less tacky than the stuff I've had to sit through for a long time -- would that a hetero scene be as tastefully done. Overall : mostly harmless, but not something I would have gone out of may way to see (e.g. if it were not on during a week I was taking off to watch films)

  • The Third Man -- What the hell? I mean, seriously, What The Hell!? How did this piece of solid idiot plotting get the reputation it did?

    The emperor has no clothes, is bare-ass naked as a jaybird, nude, sky-clad, in the buff, totally starkers!

    Welles wanders on briefly, acts, surprisingly, as one of the least unsympathetic of the characters (by the time you are supposed to consider him a complete blackguard), the sewers scene provides yet another counter-example for that silly "Why are manhole covers round?" interview question, but, just like with Thirst, style could not save this one. At least its age means that it is short and we were spared having to sit through any sex scenes.

Sunday, September 20, 2009

F# under the covers IV -- FxCop noise

I like to keep my .net code FxCop clean -- and especially when writing an FxCop rule set, it's pretty much part of the ground rules -- even though some of the rules tend at times towards coding for Mort to use your library (rather than educating him). However, FxCop does tend to assume you're coding in any .net language you like, so long as it's C#.

Take this example:

which emulates the C# as keyword (or C++ dynamic_cast<C *>() ) by contrast to the F# :?> which is more akin to dynamic_cast<C &>(). I don't mind the CA1004:GenericMethodsShouldProvideTypeParameter warning this gives -- but taking the F# idiomatic 'a and generating

warning : CA1709 : Microsoft.Naming : On method 'Patterns.As<a>(object)', correct the 
casing of 'a' in generic type parameter name 'a' by changing it to 'A'.
warning : CA1704 : Microsoft.Naming : On method 'Patterns.As<a>(object)', consider 
providing a more meaningful name than generic type parameter name 'a'.
warning : CA1715 : Microsoft.Naming : On method 'Patterns.As<a>(object)', prefix generic 
type parameter name 'a' with 'T'.

seems a bit excessive, even though replacing it with 'Target, like you might if you actually had to write it in C# as well, will suppress all three.

And that's just in code I write.

When the code subject to warnings is itself generated, that tends to add a degree of insult to injury. As in

which conjures up CA1707:IdentifiersShouldNotContainUnderscores from variables state_0 and state_1 in generated code that looks like

or CA1804:RemoveUnusedLocals for name x in the guard pattern

which maps to

because symbol x has to be scoped that way, as well as CA1811:AvoidUncalledPrivateCode or CA1804:RemoveUnusedLocals for entities only present in generated code.

That's debug build. In release build (not normally subject to FxCop, since you don't want to have SuppressMessage attributes floating around in what you ship) we get a different set of messages from differently shaped IL -- for

we at last get the entirely plausible CA1801:ReviewUnusedParameters (by contrast debug build's function body that assigns the argument to a write-only local causes no warnings!), and for the obvious combinator for chaining state with the Either type

we get "'arg_1', a parameter, is cast to type 'Either<x, a>._Right' multiple times in method 'Local.op_GreaterMultiplyGreater... -- but, surprisingly, no warning about underscores in names this time!

This certainly makes it harder to do the right thing, when none of the warnings, apart from the underscores one, actually seem like things that could really be called bugs as such. And it's also harder to frame alternative FxCop rules to use instead of the standard ones, rules that work with F# idiom, beyond possibly the generic type parameter naming cluster.

The debug build for the Feb 2010 CTP is unchanged from this; the release build produces more warnings for both the above cases, mainly about naming -- but also including

"In member 'Module1.op_GreaterMultiplyGreater<q, 
x, a, b>(q, Either<x, a>, FSharpFunc<q, FSharpFunc<a,
 Either<x, b>>>)', remove the underscores from parameter 
name 'arg_0'."

Book — Lady of Mazes by Karl Schroeder

Set only a few millennia hence, and confined to the re-engineered solar system, under the adventure yarn surface this is far more angsty take on being human after some sort of a Singularity than the low-end posthumans of House of Suns. What he seems to posit as the central dilemma, well, I'm sorry, I'm not seeing the problem here -- and it's not as if being unoriginal and there being many other people doing exactly the same as you are doing now has bothered many people. Towards the end, I found myself more in tune with some of the supposed antagonist factions than the nominal lead character's agenda.

Book — House of Suns by Alastair Reynolds

Pretty, but ultimately hollow Big Dumb Object/Sense of Wonder stuff, set in the (post)human-filled galaxy of 6 Myr hence. Suffers from chunks of idiot plotting (when you're fleeing from a massacre, and suspect a traitor in your midst -- identity easily spotted by someone who never manages to get ahead of the detective in a whodunnit -- you don't leave the person working on reverse engineering the answer to why this is all going on to work in solitude, you get them broadcasting every step of the work), and from needlessly firing off all the Chekov guns at the end for a totally flat finale.

Really, in a big-scope SF story, it's better if some of the wallpaper just stays that way, as odd local colour to make the setting distinct from any other, rather than having to become a plot point.

Tuesday, September 15, 2009

F# under the covers III

To date we've seen examples where some simple F# code maps to something horrid in the C# view we get from Reflector.

Now for something completely different...

Simple properties like

map quite directly from F# into IL, even in debug build

where set_Points just assigns straight into the field, and get_Points just returns it, roughly as expected.

The corresponding C#

becomes

The set_Points code is the same, modulo the maxstack -- but what are that temporary and that branch doing in get_Points?

This is a bit of a "lolwut!?" discovery!

Reassuringly, the release build of the C# get_Points is almost a nop-free version of the F# debug code

but as the debug version is the one for doing code analysis on, that's less useful.

This is unchanged with the Feb 2010 CTP (1.9.9.9).

Moving the immovable -- that McAfee SiteAdvisor toolbar in Firefox

Actually it does seem to be immovable -- I've tried a number of techniques (floats, CSS-positioning, CSS-transforms) and haven't been able to just simply move the control one pixel, let alone to somewhere less intrusive within the toolbox element.

Hiding it without disabling I can do. Here's how:

In your ...Application Data\Mozilla\Firefox\Profiles\..profile..\chrome folder, add the following UserChrome.css

Restart Firefox, and the waste of vertical space is gone.

You can tell how well crafted the control is, when you look at the XUL and see that it's a toolbaritem naked in the toolbox, rather than actually being in a toolbar.

Saturday, September 12, 2009

More F# under the covers

This is a bit of a follow up to

and was provoked by running NDepend over -- naturally -- my current .net project as a first test drive (and being a work in progress, the debug build). Which then it highlit a number of quite simple methods involving function chaining as being candidates for refactoring (as well as the tut-tutting at the code generated for the Either< 'a,'b > type).

Let's look that series of short-circuitable tests, mentioned in the first post, something that would look like

in C#.

Let's have a type that expresses the intent more directly than a general purpose boolean, and a couple of helpful combinators...

Then we can write the chained tests as

Reflector shows us that the IL that comes out of the process in a debug build corresponds to code that looks like

If the Test function being used is a member function of the class, you get temporaries like

defined and being passed into the local lambdas; and there is no re-use of these temporaries.

Fortunately, the code generated in a release build avoids creating one-shot variables for these intermediate input values (and optimizes away the call to ignore) -- but it still has a separate tuple value for each test, rather than re-using a single name. Chain enough calls together and the number of hidden variables will start to trigger metrics-based alarms.

It looks like F# code is going to be rather heavy going for tools to work with.

This is unchanged with the Feb 2010 CTP (1.9.9.9).

C# annoyance -- Generic Enum constraints

I discovered the other day that you can compile this in C++/CLI --

while the equivalent in C# tells you you can't constrain to System.Enum -- and the language deliberately goes out of its way to specifically prevent this. Nor can you tag enums with marker interfaces (they're sealed classes).

Unfortunately, even though you have the juicy IL code for IEnumConstraint, you can't actually use it in C# like --

you get

The type 'T' cannot be used as type parameter 'T' in the generic type or method 
'EnumConstraint<T>'. There is no boxing conversion or type parameter
conversion from 'T' to 'System.Enum'.

and you end up being driven back to the previous problem.

Sunday, September 06, 2009

F# algebraic types under the covers

Consider the simple type

Innocuous, right? Well look at what Reflector has to say about the May 2009 CTP version...

Most of this is tagged as [CompilerGenerated] -- with some surprising omissions, like

which makes filtering out what is written vs what is generated for coverage analysis purposes rather more tedious than it might be. Arguably, in a unit test using the type, the latter two should get exercised anyway, but having the __DebugDisplay() method left over seems like a bit of an oversight.


By way of comparison, the Feb 2010 CTP yields

which is broadly similar, but differs in detail (such as the Tags values and the DebuggerDisplay attributes -- and the bug about __DebugDisplay not having the CompilerGenerated attribute is fixed.

Tuesday, September 01, 2009

If monads did not exist, we would be forced to invent them

Over the weekend, I started myself a little F# project, a little more complicated than the little orrery clock I wrote at the end of last year -- hence the little flurry of F# unit test related posts.

The project in question is a simple FxCop rule to identify methods with inadequate test coverage, so, if I were writing this in a conventional imperative language, the

override protected ProblemCollection Check(Member member)

method would look roughly like (using the return ASAP refactoring of the arrow-antipattern)

where each check either identifies the method as a definite pass or fail (the latter mutating the object state that the overall method also returns), or cannot tell.

Translating this sort of construction to a functional language, the use of a monadic construction becomes -- if you forgive the pun -- imperative if we are not just to transcribe the if driven style literally.

Looked at in functional style, in order to make this process at all pleasant, we immediately see the State monad (for the mutable state), and some crazy variant on the Maybe monad -- a sort of AndAnd monad, perhaps? -- for the short circuiting of further checks when there is definite result. Though I might go for something a bit closer to the Haskell syntax than the F# computation expression.