Wednesday, November 07, 2007

TechEd 2007 interim swag count

Third day of TechEd 2007 and the swag-count is modest:

T-Shirts: 4
Baseball caps: 2
Misc: 1 Swaggily Fortunes winners plaque, 2 Beer cosies, 1 inflatable microphone (discarded due to slow-puncture)

The right-honourable GSF and I agree - not a vintage year...

Auto Properties & Object/Collection initializers - the presenter's friend

From being here at TechEd2007, I have noticed one thing, if nothing else (actually I have noticed lots else) is that the presenters bashing out code in live demos love auto properties and the quick initialisation capabilities in C#3.0. It makes the job of getting straight down to the umpteenth

from a in b
where c
select d

so much easier. A bit like using dynamic SQL, it saves time/errors when cutting code in front of a live audience, and so it has cropped up in loads of sessions.

Coming from a coding environment where we produce web, win and ajax controls, however, I can't say that auto properties will be figuring much in my production code; for the one reason that they cannot be decorated with attributes. Attributes are essential when surfacing control properties for governing designtime stuff like visibility, serialisation and categorisation as well as runtime stuff like data binding. Even simple private member variables need stuff like this when they are encapsulated as public properties.

The initializers on the other hand are an excellent labour-saving piece of <motsDuJour>Syntactical Sugar</motsDuJour>. Given that all that happens when the syntax is compiled is that the longer-winded versions of the constructs are created in IL, they can be seen as akin to the using block's expansion to a try-finally dispose construct in the corresponding IL.

Good stuff.

Thursday, September 20, 2007

Possession or omission with one exception - and that's all

Pointless, I know, but I'm going to get this off my chest...

How is it that so many people cannot get the use of the apostrophe correct? The rules for its use are simple and have only one exception (example of which can be found in this sentence).

Possession - "Joan's painting (noun)", "England's captain"
Omission - "That's all folks", "Don't get me started", "Joan's painting (verb)"
Exception - "It's a long way to Tipperary", "The rules for its use"

And that's all - it's not for awkward plurals like abbreviations (DVDs not DVD's) or nouns ending in vowels (casinos not casino's)

IT IS SO SIMPLE!

I feel better for that...

Friday, July 20, 2007

MSCUI - The Microsoft Health Common User Interface

Last week some of the fruits of the project I have been working on for the last 2 years at Microsoft UK, saw the public light of day as http://www.mscui.com/ and http://www.codeplex.com/mscui went live.

Microsoft have been working for some time now with the UK National Health Service to produce UI guidance for healthcare software and to produce a UI control toolkit for web and Windows development that embodies that design guidance.

Primarily centred around patient safety and standardisation of common interface elements, the guidance and tools are intended for health care ISVs to help them quickly and consistently produce web and Windows applications that conform to UK NHS standards that aid patient safety.

The stuff we devs have been working on - the web and Windows controls - are intended to enforce rules about formatting of information-display and standardising and validating the input of data to promote patient safety and reduce ambiguity. The web controls make use of AJAX and the Microsoft AjaxControlToolkit and both platforms share common specific data types and code for parsing input and standardisation of displayed information.

The intention in going public is to give the work and its output wider exposure and to create a community for feedback and input into an ongoing process of developing and extending the design guidance documentation (primarily through the http://www.mscui.com/ site) and practical support for it in the toolkit and again a community for feedback (through the http://www.codeplex.com/mscui site).

Anyway, the sites themselves describe and explain it better than I can here, but it is nice to see a public release to some of the stuff we've been doing over the past few months; and hopefully some of the stuff we are doing now, and as we move on, will make it out into the community via the same or a similar route.

Thursday, July 19, 2007

See what I mean?




OH NO! Not the BBC as well!

I saw a piece on the BBC 10 o'clock news last about supplying new helicopters to the troop-effort in Afghanistan and couldn't believe my eyes as the graphics for the numbers and types of aircraft contained the loathsome "grocer's apostrophe": Merlin's, Chinook's etc. Good grief! Were all the literate staff at the BBC too busy panicking about cancelling phone-in competitions to proof-read the captions on their flagship news programme?

Has anybody checked whether there are still ravens at the Tower of London?

Thursday, June 28, 2007

Technobile link

The online version of my Guardian Technology Technobile article is here.

Tuesday, June 26, 2007

K&R Slaves

Warning: anyone reading this might want to do so with a mental IMHO tag around the whole thing.

Long-suffering friends and colleagues know that I make no secret of disliking the code formatting convention known as K&R style (after Brian Kernighan & Dennis Ritchie and the code layout style first used in their seminal book The C Programming Language). However, although I personally believe that this:

function changeTarget(source){
if (source === Targets.localTarget){
var target = this._get_target(source);

for(i = 0; i < this._log.ops; i++){
if(this._log.ops[i].value === target){
this._logs.selectedindex = i;
}
}
}else{
this._log.selectedIndex = -1;
}

if(this.get_mode() === SourceMode.Extended){
this.addCssClass(this._popupElement, "Extended");
}else{
this.removeCssClass(this._popupElement, "Extended");
}
}


...is much less readable and understandable than this:

function changeTarget(source)
{
if (source === Targets.localTarget)
{
var target = this._get_target(source);

for(i = 0; i < this._log.ops; i++)
{
if(this._log.ops[i].value === target)
{
this._log.selectedindex = i;
}
}
}
else
{
this._log.selectedIndex = -1;
}

if(this.get_mode() === SourceMode.Extended)
{
this.addCssClass(this._popupElement, "Extended");
}
else
{
this.removeCssClass(this._popupElement, "Extended");
}
}

...I know that these things are a matter of preference and project/company standards.


No, what really annoys me are the reasons some people cite for preferring K&R over BSD/Allman code layout and the actual origins of the style itself.


There seem to be two main reasons people go for it - firstly they think it looks cool; as if making code look complicated and involved imparts some sort of geeky kudos - "look at that heavy-duty code! Must be pretty hairy stuff going on in there, best not to touch it or try to maintain it, best just to marvel at it" - however, as in the above examples, I'd go for clarity and readability any day because code shouldn't be "write-only" and needs to be comprehensible to others to allow for maintainability.


The second reason seems to be born of a "be like the big boys" motivation - "if its good enough for the giants of software like Kernighan and Ritchie, then who are we to argue?" and "all the code that comes out of the big guys at Microsoft is formatted that way", but hang on - a few issues:



  • The compacted style only emerged as a practicality of only having 80 column x 25 line displays and trying to get as much readable code into each screen or printed page as possible - we don't have that constraint anymore and who prints code listings these days anyway?

  • Kernighan and Ritchie never mandated or recommended that style - they were quite neutral in the original book about it:


"The position of braces is less important, although people hold passionate beliefs. We have chosen one of several popular styles. Pick a style that suits you, then use it consistently."


Yet somehow the style has become a sort of holy gourd.



  • Kernighan and Ritchie's original use of the style was inconsistent, (again because of constraints); the original C language didn't allow for the compacted braces style on functions that took arguments and K&R were quite happy to be pragmatic about things and adopt a BSD/Allman style for these cases

  • Microsoft's big boys don't always manage consistency either; whilst they ship the AjaxControlToolkit with lots of K&R style code in the JavaScript, their internal style and code review tools warn against elements of K&R styling when they appear in language files that the tools process (main example C#) and it is possible to fall foul of check-in policies for compliance with these code review tools on readability/maintainability grounds

Ultimately though, my point is that to go with K&R for reasons of emulation or hero-worship is spurious and slavish, and readability and comprehensibility are much better criteria by which to select a code formatting style and I will "take the Pepsi challenge" any day that BSD/Allman wins on that score - I might just have to wait for a few others to cast off their chains.

The fight continues...

The Guardian say that they are going to publish a piece I wrote for their Technobile column which is published each Thursday in the Technology supplement. The article is an extended version of my rant about big corporations misspelling my surname in correspondence, which I previously posted here. My main motivation in sending it to them is the hope that wider exposure might result in someone identifying the makers of the CRM software that seems to be responsible for propagating the spelling error to so many companies. Then I can write to them and direct my bile more effectively.

Wednesday, May 02, 2007

(Active)ActiveSync

Update on syncing my Treo 750 PDA phone:

There is at least additional software on the install CD to enable synching via Bluetooth - yeah right, like the Bluetooth stack is renowned for its rock-solid reliability and compatibility...

Well I wasn't too hopeful, but after the usual multitude of notifications about this, that and the other Bluetooth device all with individual (uncertified - of course) drivers, I got everything installed; and it all works!

Now, with only the occasional hiccup/lockup/Task Manager kill off (it is Bluetooth after all), I have a way of syncing and transferring stuff, albeit at modem speeds (well it is Bluetooth after all).

So although I won't be moving too many large files over to use in Picsel's dinky PDF viewer or ripping any DVDs to its miniSD card, I do at least have a way of getting stuff on and off the thing and a way of backing it up.

Tuesday, April 17, 2007

(in)ActiveSync

Over the years I have owned one or two PDA-type mobile devices at various times, not really using them as the workhorses of office productivity that they are often portrayed as being, but more out of sporadic curiosity and out of an interest in their programmability.

Recently I got a Treo 750 as a replacement for my mobile phone and as it also runs Windows Mobile 5.0, I find myself effectively with another PDA. This time there is more of a chance of it becoming a real everyday tool for me as it pretty successfully combines a mobile phone with PDA Pocket PC functionality.

But, and here finally is my point, over the years ActiveSync has always been a bugbear in terms of reliability and stability of configuration and use - AND IT IS STILL NO BETTER IN ITS LATEST INCARNATION! Connected once, synched, never recognised again except as an USB device error. So now I am stuck trawling the forums looking for help in resolving the issue, un-installing/re-installing (didn't work), upgrading ActiveSync from 4.2 to 4.5 (didn't work), swapping to other USB ports and other machines (you've guessed it - didn't work)...

...frustrating.

Monday, April 02, 2007

Ah! Good old .net remoting...

Looking at some .net remoting code recently reminded me of just how confusing and frustrating using it can be.

We were trying to diagnose why remoted events hooked up to a remoted object were failing after the standard 5 minutes initial lease time despite the fact that the remoted object had an overridden InitializeLifetimeService method that returned null - the standard way to setup an infinite lease on a remoted object.

Using debug tracing and explicit lease management with a sponsor class, we could prove that the remoted object was not dying, but nevertheless the events that it was firing seemed to be disconnected after the initial 5 minutes and we were getting a standard remoting infrastructure exception stating that the remote object didn't exist or was disconnected. How could it be that the remote object had an infinite lease but the events it was firing didn't?

The answer, as always with remoting, lay in understanding the hoops that the remoting infrastructure goes through in supporting cross-domain marshaling of calls, i.e. how it manages to make each side of the remoting relationship behave like it is communicating with a local instance of what is to either side, the remote object.

The curious thing is that even when a object that is remotable (i.e. derives from MarshalByRefObject) is started by a client that is not itself remotable, if the remoted object calls back to the client (as it must in order to fire an event back), then the remoted object must do so via the remoting infrastructure by communicating with a transparent proxy/real proxy local to itself which then forward the call via remoting back to the client.

In other words the client and server roles are reversed for this callback and there is effectively a remoted instance at the client to receive the call and it was this that was being created with the default 5 minute initial lease time.

This of course begs a couple of questions - firstly: what is being created on the client side as the receiver of the events? It can't be the client itself because it already exists, stays alive after the 5 minutes are up and doesn't derive from MarshalByRefObject and so cannot have a leased lifetime anyway. Secondly: how could we avoid whatever it was from dying after its 5 minute lease expired?

As it turned out the second question was easier to answer than the first, albeit with a somewhat inelegant solution.

A simple call to set the LifetimeServices.LeaseTime static property to a very large figure (say 1000 days) within the client app's initialization, sets the initial lease time for any MarshalByRefObject subsequently created in its AppDomain (including the dynamically created proxy that was previously timing out at the default lease time of 5 minutes) to what is effectively an infinite lease (unless you want to go 27 years without shutting the client app down!)

Of course a more elegant solution would be to actually have created our own client side MarshalByRefObject derived class to serve up the events to the client app and then to have overriden the InitializeLifetimeService method to return null as we do on the server side, but that really wasn't necessary as the only remoted functionality on the client end was the servicing of these events and we could safety define a long default lease for all remoted objects created in the AppDomain and achieve the same effect without another layer of indirection and the effort of creating and testing more code.

As for the answer to the first question...that's more difficult to answer; from debugging, it is clear that there is a TransparentProxy created on the server side which is used to fire events back to the client side, but what it is connected to, through the Remoting framework, down at the client side is difficult to establish (although I must admit I didn't spend too much time trying, after establishing the easy fix solution) - all the client is attached to, is an event that may or may not fire depending on whether it is connected to a valid source or not.

Perhaps someone more familiar with the Remoting framework knows more about the mechanics that go on under the hood when "doing events" on remotable objects and how non-remotable objects can effectively work as remote servers when the remote objects they create need to fire events back to them; it would be interesting to know...