Thursday, December 09, 2010

Mark Twain

A Plan for the Improvement of English Spelling
by Mark Twain


For example, in Year 1 that useless letter "c" would be dropped to be replased either by "k" or "s", and likewise "x" would no longer be part of the alphabet. The only kase in which "c" would be retained would be the "ch" formation, which will be dealt with later. Year 2 might reform "w" spelling, so that "which" and "one" would take the same konsonant, wile Year 3 might well abolish "y" replasing it with "i" and Iear 4 might fiks the "g/j" anomali wonse and for all. Jenerally, then, the improvement would kontinue iear bai iear with Iear 5 doing awai with useless double konsonants, and Iears 6-12 or so modifaiing vowlz and the rimeining voist and unvoist konsonants. Bai Iear 15 or sou, it wud fainali bi posibl tu meik ius ov thi ridandant letez "c", "y" and "x" -- bai now jast a memori in the maindz ov ould doderez -- tu riplais "ch", "sh", and "th" rispektivli. Fainali, xen, aafte sam 20 iers ov orxogrefkl riform, wi wud hev a lojikl, kohirnt speling in ius xrewawt xe Ingliy-spiking werld.

Tuesday, November 16, 2010

.NET: IEnumerable is *not* lazy

Just spent ten minutes working this one out.

If you have a variable

IEnumerable<Foo> SomeFoos = [...LINQ expression returning an enumerable...];

and then do this

foreach (var foo in SomeFoos) { [...update foo...] }

you will almost certainly not see any changes in the values in SomeFoos.  Why not?  Because each time you iterate through SomeFoos, the enumerator is run again, quite possibly recreating each item.

A solution is to force each item in SomeFoos to be manifested once.  For example,

List<Foo> SomeFoos = [...LINQ expression returning an enumerable...].ToList();

Now things will work as expected.

[N.B.  When I say "laziness", I refer to the standard functional programming practice of replacing an evaluated thunk with the result, thereby avoiding any repeated processing effort on subsequent reads of the thunk.]

Thursday, November 11, 2010

WPF: Making ListBoxItems stretch the width of the ListBox

This is unbelievably hard for something which must be universally desired.

By default, ListBoxItems occupy the width required by their contents, not by the width of the containing ListBox.  This causes your optimistically formatted columns in each ListBox to fail to align.

Instead, add this in the Resources section:


<Style x:Key="StretchingListBoxItemStyle" TargetType="ListBoxItem">
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>


and add ItemContainerStyle="{StaticResource StretchingListBoxItemStyle}" to your ListBox attributes.

Strewth.

Friday, October 01, 2010

Making things stretch in WPF

I quote from a StackOverflow reply by one Matt Hamilton:
There are also some properties you can set to force a control to fill its available space when it would otherwise not do so. For example, you can say:
HorizontalContentAlignment="Stretch"
... to force the contents of a control to stretch horizontally. Or you can say:
HorizontalAlignment="Stretch"
... to force the control itself to stretch horizontally to fill its parent.
That should come in handy in future.

Thursday, September 30, 2010

Synchronization in .NET: ManualResetEvents and Monitors

I recently needed to simultaneously wake an arbitrary number of waiting threads, each waiting on some condition.  My first approach was to have a shared ManualResetEvent, a subclass of EventWaitHandle with the property that "Once it has been signaled, ManualResetEvent remains signaled until it is manually reset. That is, calls to WaitOne return immediately." (MSDN docs.)  [.NET also has AutoResetEvents, but with these only one waiting thread is woken when the event is signalled.]

The idiom I was using was this: I had a global ManualResetEvent called WakeUp; threads waiting on the condition would call WakeUp.WaitOne() (causing them to sleep until...); a thread identifying the waking condition would call WakeUp.Set(); WakeUp.Reset().  My reading of the MSDN documentation is that the call to Set() should wake all waiting threads, while the call to Reset() should reset the event handle for the next wake-up signal.

Tragically, this did not work and my program would randomly flounder.  If I added a delay between the Set() and Reset() calls, the likelihood of floundering reduced, but wasn't eliminated -- and, besides, that is too disgraceful a hack to contemplate for more than a moment.

The right solution was to use a Monitor.  The idiom here is as follows:

For Threads Waiting On Some Condition


Monitor.Enter(SyncObj);
while (!condition) { Monitor.Wait(SyncObj); }
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  while (!condition) { Monitor.Wait(SyncObj); }
}

For Threads Establishing Some Condition


Monitor.Enter(SyncObj);
// Establish condition.
Monitor.PulseAll(SyncObj);
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  // Establish condition.
  Monitor.PulseAll(SyncObj);
}


Peace at last...  (For the curious, in this particular application it would not have been sensible to set up a separate event handle for each condition, which is what one would normally do.)

Wednesday, September 22, 2010

State Machine Compiler

I've just read about SMC, an open source state-machine compiler targetting multiple languages, including C#.  I can see this coming in rather handy.

Monday, September 13, 2010

Trouble with nulls

Following a conversation with a colleague, I have decided to put to paper what I think is wrong with nulls.

Essentially, this: to the compiler, null means "uninitialised".  It is the default value given to references.

As programmers, however, we invariably overload null with other meanings, such as "the empty list", "the empty string", "the unspecified option", and so forth.

This is bad, because I want the tools (compiler, debugger, etc.) to tell me the difference between "I have forgotten to initialise this variable" and "I have put the wrong value in this variable".

As it is, I end up with a bastardised mixture of meanings in my code requiring a lot of checking that would otherwise be redundant.

Maybe code contracts will be able to clean up this mess...

Monday, September 06, 2010

Equality in C#

Here is a good article on the subject.

I wish, I wish, I wish that C# had ditched nulls and default reference equality; that's such a 1960s resource limited way of thinking.  Equality should mean structural equality by default; one should have to explicitly ask for reference equality or nullable types.

Oh well, here's the summary:

  • Implement IEquatable.Equals(T).
    • Remember to check for null and reference equality.
  • Override object.Equals(object).
  • object.Equals(object, object) does what you expect by first testing for nulls and reference equality.
  • Override object.GetHashCode.
  • If you implement == (reference equality by default), also implement !=.
  • Implement the == and != operators for value types to avoid the need for boxing.

Wednesday, September 01, 2010

WPF and XAML

WPF is Windows Presentation Foundation.  It seems like a first class framework to me.

XAML is Microsoft's eXtensible Application Markup Language.  It is a way of describing user interfaces in XML.  It is rich and powerful.

But, why, in the name of all that is holy, is it not composable?!  For the life of me, I cannot understand why a fragment X works as expected in context Y, but not in context Z.  Nor does the documentation I have been wading through (as in, trying to make progress through the Augean stables) been of any help.  The whole of the net is filled with anecdotal solutions to common problems with, so far, not one whit of a general set of principles to help guide one through the quagmire of UI development using XAML.  I am giving serious consideration to not using it on my next project, but rather coding everything up directly in C#.  I would put money on this being vastly more productive.

I have just ordered a book on the subject that sounds as though it will explain things to my satisfaction ("Applications = Code + Markup" by Charles Petzold, who is apparently something of a luminary).  Of course, this being a modern programming book it doubles as a keep-fit device, weighing in at something over 1000 pages.

Tuesday, August 10, 2010

PowerTab for PowerShell

PowerShell is excellent.

The default command line environment was obviously written by a bunch of monkeys (who on Earth wants to block select rectangles of text rather than lines of text?).

PowerTab is a module that goes some way towards fixing the woeful keep-tabbing-until-you-hit-the-completion-you-want tab-completion behaviour.

Thursday, August 05, 2010

Dates and Times and Timezones and .NET

Yesterday I learned something about parsing dates and times.  I was trying to get a .NET application to process date/time strings of the form "2010-08-04T16:30:00 CEST" using DateTime.TryParse.  This approach didn't work because .NET doesn't grok timezone strings like "CEST" (Central European Summer Time).

My first thought was that since CEST is defined as UTC+2 (i.e., Universal Coordinated Time plus two hours), I could rewrite these date/time strings as "2010-08-04T16:30:00+02:00", which DateTime.TryParse can handle (note that the timezone delta on the end must be subtracted from the preceding date/time to obtain UTC).  My attempts to tackle this were stymied by the fact that timezone names are not unique.  For example, CST can mean either Central Summer Time or Central Standard Time, and that's just in Australia!

So, to conclude, for the love of all that is holy, don't use timezone names in your date/time strings.  Use attached UTC deltas instead.

[For those who are wondering, as I did, the difference between UTC and GMT is never allowed to exceed 0.9s; UTC is atomic clock time with some leap seconds added here and there; GMT is not.]

Thursday, July 29, 2010

DNS Problems with Blizzard's StarCraft II Patch Installer

After much anticipation, my copy of StarCraft II arrived in the post yesterday.  I installed it.  I ran it.  It immediately started downloading a patch.  Ten megabytes later, I lost all internet connectivity.  Again, again, and a-bloody-gain.  Now, it turns out I had recently upgraded to Windows 7, a thing of beauty, which automatically ran a network diagnostic tool and reported that there was a problem with the DNS service.  Hmm, thinks I, maybe iiNet (who are my otherwise rather good ISP) have cocked up their DNS server.  After a bit of resettery, I discover that Google have a publically available DNS server (8.8.8.8).  I add this as the backup DNS server and, lo and behold, glorious sustained connectivity.

Having shared this with you, I am now about to abandon society and join the StarCraftiverse for some time.  Adieu.

Friday, June 25, 2010

Changing Jobs!

After nine excellent years at the University of Melbourne, I'm leaving to take up a new position as a senior software engineer at an IT firm in the heart of Melbourne.  I'll miss working with everyone at the University, but I'm also very excited about the new challenge.  The chaps here had a whip-round and bought me a 1997 Speyside single malt.  FANTASTIC!  This bottle is what I believe is cask strength, at nearly 60% alchohol, and will have to be approached with caution.

Farewell drinks tonight!

Wednesday, June 09, 2010

Searle on Deconstructionism

This is John Searle's priceless take on deconstructionism. One footnote is particularly amusing:
I said that deconstruction had found little appeal among professional philosophers. But there are some notable exceptions, much prized by deconstructionists. They tend to be ambiguous allies. One of these characterized Derrida as "the sort of philosopher who gives bullshit a bad name." We cannot, of course, exclude the possibility that this may be an expression of praise in the deconstructionist vocabulary.

Wednesday, June 02, 2010

A marvellous crytpic crossword clue

Clue: hijklmno (5 letters)

Answer: water (highlight with your mouse to see the solution).

Saturday, May 01, 2010

C# Namespaces

Do not use the same name for a namespace and a class.

It only leads to madness and divorce.

I've just spent a merry half hour finding this out.

Friday, April 30, 2010

WotD: tropology and tropometer

From Jarrold's Dictionary of Difficult Words:

tropology, n. figurative style of writing; interpretation of Bible stressing figurative nature of language.

tropometer, n. instr. measuring rotation.