Tuesday, May 31, 2011

CodeDOM and poor man's lambdas -- Part 2

Unfortunately there is one major sticking point in getting the generation to work for F# -- local variables are declared as let mutable rather than as a ref type which means that the necessary closure cannot be made; this is rather stronger than the lack of support for CodeDefaultValueExpression, which can be fudged around, or for nested types (which just become mutually recursive), though with up-front decision as to the language to generate (rather than making the choice following the expression tree), we could replace problematic elements with snippets.

That aside, the main operation looks like this, similar to the previous examples

If we eschewed F# support entirely, and used a partial class, then we could skip the constructor and field declarations and provide the input by any other mechanism of our choice in a hand-written part.

Generating the closure classes is a simple matter -- especially as the names of the parameters can be used as fields directly without any sigils, provided that they never contain the @this or proxy name by convention. This makes the closure class approach slightly simpler than a snippet driven use of direct lambda syntax, where local variable names to hold out parameters would in general have to be generated so as not to clash with any of the arguments:

where the individual field declarations have to work around the decorations for out or ref, thus:

The generation of the proxy methods is equally mechanical

So, given a simple type

we generate

The F# code contains

Manually replacing this with

then shows up on the next line

as an error The mutable variable 'proxy' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.; and as there are no readonly locals in the CLR -- it's all F# compiler magic that gives the illusion of same -- we're stuck with no control to tweak to make proxy immutable in the F# output.

Monday, May 30, 2011

CodeDOM and poor man's lambdas -- Part 1

The CodeDOM expression methods are stuck at the level of .net 2.0, and look unlikely to grow further support for further syntax outside of feeding it in as literal strings using the System.CodeDom.CodeSnippet* classes -- which takes away the cross-language spirit of the whole library.

So, what to do when we want to generate code containing lambdas?

Well, the obvious way is to strip away the syntactic sugar involved in the lambda/closure notation and generate explicitly what the compiler is doing for you under the covers anyway.

So, to take a case which is relevant to my interests, if we have a method (of static type Wrapper, say) --

public static T LogCall<T>(string name, Func<T> call)

that will perform some pre- and post- call logging around invoking the delegate; and we have a method

public int DoIt(int argument, out string result)

which we want to invoke through the LogCall method (considered as a decorator to the action). Writing this by hand, we would want a decorator type containing a matching method something like this:

which exposes the same interface, and delegates to the real logic in the contained object wrapped.

If we examine the code that is actually generated by compiling this, we see that the whole closure is replaced by a synthetic private inner class with a public field for each object closed over -- in this case all the arguments to the DoIt method, plus a this reference for the decorator -- and a method that stands for the lambda, which, generated names aside, looks like:

while the wrapping method looks like

And now, while the analogous F# code would probably return an int * string tuple, rather than an out parameter for multiple returns, the equivalent code snippet will do the job, just changing the types of the Func object; and the literal transposition of the C# code, out parameters and all, should still work, cross language.

In the more general case, of lambdas with arguments, then the method in the proxy type has the same arguments as the lambda needs; and in the case where no variables are being closed over e.g.

Func<int, int> square = x => x*x;

there is an optimization that the supporting method can be made static on the enclosing type, rather than requiring an object to hold the closure references.

In part 2, having simplified the problem, we can move on to using the CodeDOM to generate the LogCall decorating method and closure, given a MethodInfo.

Sunday, May 29, 2011

C# under the covers -- Enumerators

Following up on the comment stream to an earlier post, a few little bits revealed by the investigations, with a little help from ILSpy:

yield break;

is the equivalent of


inside an iterator function -- by which I mean that any silent exit from the method is compiled to the equivalent of an explicit yield break;, and

foreach(T x in y) { ... }

on exit from the iteration calls the Dispose() method of the IEnumerator<T> it uses implicitly to iterate over the collection y; whereas, of course, explicit use of the enumerator MoveNext() and Current do not.

The behavioural constraints of IEnumerable are weak enough as it is, being silent on whether replayability is part of the contract or not; this inconsistent disposal (with the IDisposable interface being added only to the generic IEnumerator<T> and not the .net 1.x vanilla version) makes guessing behaviours even worse when using LINQ methods like Skip which does the dispose via using when the iteration is exhausted

and Take, which does it implicitly by the foreach route before the iterator has been completely drained

There are probably similar wonders waiting to be unearthed in the F# collections APIs as well.

Friday, May 27, 2011

Belated Reviews — Anime

Otome Youkai Zakuro

Japan, about 100 years ago; and the pace of modernization is causing disturbances amongst the spirit folk. So a Ministry of Spirit Affairs is set up, and a number young army officers assigned to liaise with representatives of the magical folk. Being a shoujo, this means that there is a pretty fox girl (or two) for each of the handsome young men, including the eponymous Zakuro for Agemaki, the male lead, and all the necessary flowers and sparkles to show where True Love is blossoming.

The series is best at the start -- introducing the characters, setting up the different romances, and nodding to the premise with a spirit-of-the-week to resolve, from the kami whose shrine has been demolished to make way for a station hotel, to the mysterious presence haunting Agemaki's family home. Alas, after the half-way point, it grows a LOLplot, involving Zakuro's mysterious past, and rather trips over itself -- the Serious Business being rather too much for the previously established light-hearted romance set-up.

Super Robot Wars OG — The Inspector

Coming in from the cold to what is actually the second season of this title, I just rolled with it, figuring out as I went along which of the many factions were supposed to be the good guys and which the villains -- because I didn't find this guide -- and just kicking back to watch the escalating battles, goofy robots, and Itano circus.

This is what anime ought to be more like -- not the endless highschool rom-com, or cute girls being cute for the otaku to perv over.

Letter Bee REVERSE

The first season ended on a cliff-hanger, where Lag's erstwhile mentor and role-model Gauche Suede appeared as one of the enemies of the whole Amberground system; and the second season carries on with the struggle between the Letter Bees, and the conspirators in REVERSE who are plotting to extinguish the artificial sun which lights this world (hinted to be Earth in some distant future).

Surprisingly, for the thwarting of such an existential threat, there is little by way of revelation (we never see the sunlit lands of Akatsuki, only the twilight regions; the various hints at deeper things going on, the very nature of the artificial sun are raised as hints, but never revisited), revolution (we return pretty much to the status quo ante after the whole secret war), or repercussion (after the threat is averted, all the elements that would disturb the status quo simply migrate to a backwater town, while Lag returns to his normal rounds as a delivery boy).

Definitely a case of better to travel hopefully that to arrive.

Level E

In what seems to be Japan's answer to Men in Black, we have a setting where Earth is a way-station for many alien races, all staying undercover, in an uneasy truce despite existing enmities. And then the Prince of the race in nominal charge of the planet comes to visit.

This would not be so bad, were it not for the fact that Prince Baka is a trickster with little restraint, while his minders are trying to keep any interstellar incident from being set off.

Thus kicks off the case of the long-term enemy race who are serious baseball fans, the random highschoolers who are turned into a sentai team (and their alien assassin teacher), the hive-queen who comes to Earth looking for a mate (and finds something other than she'd expected), the last of the twin-tailed mermaids, and finally Baka's betrothed and brother who are determined to see him wed. Baka sails through all this in total serenity, while his minders sink further into helpless rage.

Adapted from a 15 year old manga, it stuck out from all the other titles on offer for the first quarter.

Currently watching

Mobile Suit Gundam -- and that's it.

The only one of the current season's offerings I might have tried (Hyouge Mono) isn't on Crunchyroll, and even were I to go back into the grey world of fansubs, it's a title that has all the hallmarks of a series that will never get fully subbed for years.

Tuesday, May 24, 2011

Spring Cycling 2011

A short holiday in a spell of warm, bright but very windy weather. I started by doing a quick spin out to lunch at the Crown and Punchbowl on Saturday, returning along the towpath; then set out to re-do one of the short tours that I did a couple of years ago

View Spring 2011 in a larger map

There was a sprinkling of rain on the Sunday lunchtime, and again overnight on Monday, but that was really of no consequence, unlike the previous time. The wind, however, was a different story, making the going a slow grind, and the journeys not so full of detours as before.

The minor road into Stowmarket was closed, as I discovered on the way in; so I tried to follow the intended route -- only to miss a turn and only realise on reaching the A140, so looped back to the intended route after crossing.

So, by the time I got to Cotton, it was about opening time -- and thus started a litany of non-functioning pubs, ending up at the Waterfront Inn in Diss where I could get food as well as drink in mid-afternoon. Just as well I had a substantial meal, as it turned out that the kitchens at the Scole Inn close on Sunday evenings.

The next morning, looking at the time and weather, I made the journey to Framlingham, stopping at Stradbroke to pick up some juice and biscuits, and them pausing on convenient benches to rest and read a while, arriving in time for a late lunch, and plenty of time to amble around the castle.

Castle from Gatehouse

Castle from Gatehouse

The weather continuing windy, the massive detour I did the previous time was out of the question, so instead I stopped at Sutton Hoo, doing all the woodland walks, as well as the exhibits; and rehydrating with coffee and soup.

The GAR seat

The GAR seat at Sutton Hoo

One final stop at the Dog at Grundisburgh, then the final leg into the wind; and the official return route using the cycle crossing for the A140, rather than my more usual approach from other directions.

Friday, May 20, 2011

CodeDOM -- generating an interface to a type

This is a fairly simple process -- reflect over the public properties and methods, and generate a matching interface member, rather like this:

which puts the required namespaces into order (TODO: sort System.* ahead of the rest).

The two functions look much the same, so could be factored further:

which special cases the indexer property; and

(TODO: generics and attributes, which I don't need for my immediate use case)

To make the code look less cluttered, to get type specifications which aren't fully namespace qualified everywhere, we want to specify types with keyword synonyms by type object, and the rest by name (with the namespaces included by using or open). So we have helper functions

where again, TODO handling generic types, especially collections, to get them looking pretty.

So if we use string as the type, and dump to C# we get

and in F#

where interestingly, the sorted order of the inserted members is reversed.

Monday, May 16, 2011

Hello CodeDOM -- building C# and F# code from F#

A five-finger exercise in CodeDOM using the "Hello World" example from F# -- more interesting stuff to follow later:

which yields up

which isn't StyleCop compliant, but is otherwise well formatted; and

which is a little idiosyncratic; the GUID-named types seem to be there in case of need from some construct that is not actually used in this simple example.

Now it just comes down to assembling to code object graph for something practical.

Sunday, May 15, 2011

Not sure if bug...

...but I set it to the fsbugs e-mail anyway.

Let's start with this F# code:

The last function maps to C# as

Now change the initial F# line to be namespace rather than module...

File1.fs(9,18): error FS0755: The 'CompiledName' attribute cannot be used with this language element
File1.fs(15,18): error FS0755: The 'CompiledName' attribute cannot be used with this language element
File1.fs(19,18): error FS0755: The 'CompiledName' attribute cannot be used with this language element

So for comparison purposes, let's replace CompiledName with Obsolete, and see what we've built...

where I can't for the life of me see the difference.

This happens when building using the latest compiler release in either VS2008 shell or VS2010 shell; or from the command line using MSBuild for either .net3.5 or 4.

Friday, May 06, 2011

Fixing missing volume and network tray icons

On some Vista systems, there's an intermittent corruption of the icons that give network status and volume control in the system notification "tray".

Running this PowerShell script will clear the wedged icons and restart explorer