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"/>

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


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:
... to force the contents of a control to stretch horizontally. Or you can say:
... 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

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

which can be abbreviated to

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

For Threads Establishing Some Condition

// Establish condition.

which can be abbreviated to

lock (SyncObj) {
  // Establish condition.

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

Thursday, April 29, 2010

WotD: ambry and ambsace

From Jarrold's Dictionary of Difficult Words:

ambry n. niche; cupboard, espec. containing sacred vessels in chancel.

ambsace n. double ace; lowest score; bad luck.

Wednesday, April 28, 2010

False positives

Consider an individual X who is tested for a disease.
Let D mean "X has the disease" and -D mean "X does not have the disease".
Let T mean "X has tested positive for the disease".
Let P(A) mean "the probability that A is true".
Let P(A|B) mean "the probability that A is true given that B is true".

We are given P(D), P(T|D), and P(T|-D).
(i.e.: the probability that X has the disease; the probability of getting a positive test if X really does have the disease; and the probability of getting a false positive test if X actually doesn't have the disease, respectively).
Note that P(-D) = 1 - P(D).

What is P(D|T)?
(i.e.: what is the probability that X has the disease given that X tested positive for the disease?)

Let u = P(D).P(T|D) be the probability that X tests positive and has the disease.
Let v = P(-D).P(T|-D) be the probability that X tests positive and yet doesn't have the disease.

These are the only ways X can get a positive test result. It follows that

Solution: P(D|T) = u/(u + v)
(i.e.: the probability that X has the disease given X tested positive is the fraction of positive results for X that are actually correct).

Practical application.

Since disease is rare, P(-D) will be much larger than P(D). Therefore if P(T|-D) (the chance of a false positive) is not very small, then v = P(-D).P(T|-D) will be large, hence P(D|T) will be relatively low (i.e., a positive test will probably not mean that X actually has the disease).

Bottom line: make sure your tests have a low false-positive rate.

Friday, April 23, 2010

Covariance and Contravariance

On occasion I've mixed these terms up. Taking X : T to mean "X has/is compatible with type T", then:

X : T is covariant if X can also take on a subtype of T;

X : T is contravariant if X can also take on a supertype of T.

Consider the expression Ys = map(F, Xs) where
Xs : list(Tx),
Ys : list(Ty), and
F : U -> V.

Clearly F must accept values of type Tx (or some supertype thereof), therefore U must be of type Tx (or some supertype thereof), hence F is contravariant in its argument.

On the other hand, F must return values of type Ty (or some subtype thereof), therefore V must be of type Ty (or some subtype thereof), hence F is covariant in its return type.

Monday, April 19, 2010

Ugly Betty - Nooooooooo!

Ugly Betty has aired it's final episode. We grow sad...

UB was the finest, smartest comedy I've seen on television and the cast and scriptwriters managed to maintain the level from start to end throughout all four of its seasons. Good for them for finishing it well rather than running the show into the ground.

UB was the comedy that the West Wing writers could have written. It was just that good.

Saturday, April 03, 2010

My First StarCraft On-line Win!

Kum bay yah, I have finally won a game. This is more of an achievement than you think given how bad I am at StarCraft. (I play as 'theoctopi' on ICCup if anyone's interested.)

Extended C type generator tools

I've extended my set of C tools for generating common data types. Now there are generators for list types, 'maybe' types, and expanding array types. Now with one command line invocation you can generate hundreds of lines of bug-free (!) boilerplate C code.

Tuesday, March 30, 2010

Tool for generating algebraic types in C

I've spent a few evenings crafting a tool to automatically generate C code implementing algebraic data types (or discriminated union types) from short specification files. For example, the following specification
@ type a_b_tree
@ constructor a
@ constructor b
@ constructor branch
l : a_b_tree *
r : a_b_tree *
    if (l == NULL || r == NULL) {
        fprintf(stderr, "a_b_tree: branch cannot have NULL arguments.\n");
@ end
expands to 144 lines of C (counting the .h and .c files).

The transformation supports
  • generation of constructor, deconstructor, and freeing functions;
  • optimised handling of constructors with no arguments (memory is not allocated for separate instances of these);
  • optimised handling of types with only a single constructor (there is no need in this case to distinguish between the type and its constructor);
  • user specifiable malloc and free functions;
  • user specifiable header and footer code for the generated .h and .c files.
You can download this tool here.

Thursday, March 11, 2010

The anomaly method and UHI

This is rather interesting. It seems the anomaly method of only considering digressions from the mean of a temperature series (i.e., the series' anomalies) does account for the urban heat island effect (i.e., it effectively removes the unwanted UHI component from the signal).

Thursday, March 04, 2010


This is witty and helpful.

I particularly like
  • Don't string too many prepositional phrases together unless you are walking through the valley of the shadow of death.

Monday, March 01, 2010

Cute "proof" of Pythagoras' theorem

[For reasons I have yet to fathom, the ASCIIMathML plugin doesn't want to work for this page...]

I'm reading The Mathematical Mechanic by Mark Levi, a tour of various mathematical results that can be obtained much more directly (albeit without proof) by appealing to our mechanical intuition.

Here's a beautiful proof from the book of Pythagoras' theorem, `a^2 + b^2 = c^2` where `a` and `b` are the opposite and adjacent sides of a right angled triangle and `c` is the hypotenuse.

Consider an ice skater of mass `m` on a perfectly smooth ice rink. The skater starts in the South West corner of the rink and pushes off against the South wall; the skater is now moving North with velocity `a` and hence has kinetic energy `ma^2/2`. Next the skater pushes off against the West wall and adds an Easterly component `b` to their velocity. The energy acquired from this second push is `mb^2/2`. Now, the skater's overall velocity is `c` and overall kinetic energy is `mc^2/2`. But this must be the sum of the energy acquired from each push, hence `ma^2/2 + mb^2/2 = mc^2/2`. Cancel the `m/2` terms and you have Pythagoras' theorem!

Wednesday, February 24, 2010

A roguelike I can enjoy

Dungeon Crawl is a roguelike that I can actually enjoy over a coffee break (i.e., I don't have to dedicate years of my life to it). And you can play it over ssh.

Tuesday, February 23, 2010

Latin phrases

  • "Nil carborundum illigitimi" - don't let the bastards get you down.;
  • "Nullius in verba" - take no-one's word for it (motto of the Royal Society, apparently suspended for climate related issues);
and my personal favourite:
  • "Sic biscuitus disintegrat" - that's the way the cookie crumbles.

Monday, February 22, 2010


There's an interesting discussion on probability at William Brigg's blog.

Briggs claims, and is supported by some of his readers, that given

  • I have some six sided object in my pocket
  • Exactly one face is inscribed with '6'

we can conclude

  • P(a '6' shows uppermost after a roll) = 1/6.

I, and some other readers, contend that no such statement can be made. The discussion is interesting because some, like myself, see probability as a description of reality, whereas others see probability as a description of a state of knowledge.

I'll be fascinated to see how this one turns out.

Saturday, February 20, 2010

Nuclear Power and Sustainability

This is excellent: all the costs and numbers in context. If there's one good thing about AGW madness, it's that nuclear power is back on the table as a viable option.

Tuesday, February 09, 2010

Global temperature reconstructions

This is an interesting and large collection of temperature reconstructions derived from various proxies. There is a pronounced Mediaeval Warm Period in most of them.

Monday, February 08, 2010

Homeopathic dilutions

This is a hoot!

A quote from the full article:

Molecules are tiny: it takes about a billion of them to cover a standard metric full-stop. To put homeopathy in a medicinal context, if you wanted to consume a normal 500mg paracetamol dose you would need ten million billion homeopathic pills. Where each pill is the same mass as the Milky Way galaxy. There is actually not enough matter in the entire known Universe to make the homeopathic equivalent of a single paracetamol pill.

Wednesday, January 20, 2010

I dearly love the English language

I like things to be simple and regular.

Except for English. And women.

You should also read this.  I particularly like
  • "Beware of malapropisms. They are a communist submersive plot."
  • "Don't string too many prepositional phrases together unless you are walking through the valley of the shadow of death."

Gnu readline wrapper

I've just come across rlwrap, a neat little readline wrapper for other scripts and programs.