Electronic ink makes it into a consumer product – the Sony Librie. Only available in Japan atm, I think, but I’ve been waiting for one of these for a while. They’re selling it with a proprietry drm’d ebook reader on it, but it’s running linux and their source bundle includes what appears to be a framebuffer interface to the hardware. It prompted me to read about DRM technology, to see if there’s any good drm solutions out there in the research world, as opposed to the heavy-handed approaches popular by the big player. Anyhow, with the Librie, it’s the hardware which is tasty – 170dpi 800×600 reflective display, usable indoors and outside. Must find an importer …
Month: May 2004
Little rays of happiness
I finally got around to buying a replacement axle for my bike today to replace the quick-release one which some eejit took from my bike a week ago. (When I texted Susan to tell her what’d happened, my predictive text didn’t know many of the words I used to describe said person). So, I went to the Bicycle Repair Man (a shop in Newington) and the bicycle repair man (the man who works there) said “Ah, this is what you want” and pulled a packet containing front+rear spindles from the shelf, marked with the princely sum of twelve pounds. Now, I thought “that’s going to be expensive, given that I only have a use for a front spindle”. But, before I said anything, the guy had already opened the packet, took out just the front spindle and said “that’ll be six pounds”.
Yay! How nice is that? Most shops would’ve used that as an opportunity to extract maximum money from me … “I’m sorry sir, they only come in packets of two”. Instead, I got the part I need, the other spindle will get used to fix someones bike eventually, and the guy has got one happy customer who’s going to back there in future and tell all his friends about it. Yay for the Bicycle Repair Man in Newington! 🙂
Monads by stealth
Common coding idiom: A window sometimes has a tooltip associated with it. A file object may be currently open, and therefore has a current offset, or it may be closed in which case it doesn’t. In both of these cases, maybe we have the extra data or maybe we don’t – it depends on the object’s state.
Mostly in C++, people use pointers for this. The window object contains a pointer to the tooltip object which is valid when the tooltip is relevant, and null the rest of the time. To me, this is a mediocre solution.
Before I go any further, I’d better explain that one of my strong beliefs is that you should be able to get a really good idea of how a class works just by looking at the data members (ie. the state) of the class. You shouldn’t really need to read the implementation. I find this a pretty useful test of code quality and code complexity. Classes which have been prematurely optimised will show up as having more data/state than they Really Need To. Classes which don’t have a single well-defined responsibility will often stand out because they have extra “I’m currenlty in this state” flags. Well-written classes will have distilled their state down to the absolute essentials, and every data item should be able to justify their inclusion.
Furthermore, it’s always a good idea to convey as much of your intent in your source code as possible. If an object owns another object, it is much better to use an auto_ptr than a raw pointer, since that’s their raison d’etre. Spare a thought for the guys who have to read your code six months later, and be as precise as possible with your data types. If the object owns the other object from birth until death, use a const auto_ptr, since that’s all that a const auto_ptr will allow. (Of course, this only works if everyone understands the implications of the idiom. But describing idioms once to people is much easier than having to document the hundreds of places in the code where the idioms use would’ve made things cleaner).
Anyway, back to the “maybe has it, maybe doesn’t” story. Most people use pointers for this. I called this mediocre because using a pointer doesn’t convey the “might be valid, might not” intent. I’ve seen people using a convention of suffixing pointers with 00 to indicate “may be null” – as in “if (window->tooltip00) {..}”. That’s a useful convention, but it’s not something which a compiler can check.
Another common approach to this problem is to define a Maybe (aka Optional) datatype. It’s a simple thing – a Maybe
This has some advantages over using a pointer. For a start, it’s pretty clear this this “maybe data” may be present or may not be present, and so that’s a big win in terms of communication. Also, it doesn’t force you to switch to handling data by-reference like pointers do.
But it’s still not perfect because there’s no way for the compiler to verify that your program only calls get() on maybe-values which have real data. Sure, you can add a runtime check but it would be much nicer if we can verify this property of our program at compile time.
One thing which strikes me is that every place where processing of a Maybe<> value occurs we end up with an if-statement to check whether or not it’s valid. That’s a shame, since it’s basically code duplication all over the shop. Is there a way we could push this duplicate conditional code inside the Maybe<> class itself? Can we take the two bodies of the conditional and pass them to the Maybe<> class to process?
At this point, we’re kinda thinking upside down. Rather than thinking of Maybe
(Well, it’s a pretty limited idea when we’re using C++ because creating functions is fairly work-intensive. You have to figure out what data they need, and pass it to them. If we used a better language (like, maybe, ocaml!) – which allowed you to treat functions as flexibly as values, creating them on the fly, automatically capturing their context, and passing them around as easily as if they were integers – then it’d be a much more powerful notion).
So, this has been a refactoring of the Maybe<> class from a simple passive data container into a more active participant (albeit a refactoring which can’t be expressed particularly elegantly in C++). It was driven by a desire to more fully express our intent in the source code, and to ensure that we always deal with the two cases (data, and no-data) every time we process a Maybe<> value. But what we’ve done is interesting. We went from a situation where the Maybe’s state was externally visible, to a situation where it was safely wrapped up inside the Maybe object and could only be acted upon by the “special tongs” of the two function we passed to the Maybe<> object.
A lot of work for a little advantage? Nah, now you’re basically playing with a monad, and you never even noticed.