davidfindlay.org

a man, a plan, a cake: nirvana

Cabel Sasser's talk at C4

I just finished watching Cabel Sasser, from Panic Software, talking about the design and development of Coda, their website development application, at the C4 Macintosh Developers' Conference. He's a great speaker: very dynamic, and funny, and his mannerisms bear an eerie resemblance to those of someone who used to work with me. His Keynote slides were good too; I must remember to include a vomiting kid in my next presentation!

Here's the video from the talk; highly recommended.

Lambda Functions and Closures officially in C++0x

Herb Sutter just posted about the most recent ISO C++ Standards Meeting. The most exciting news is that lambda functions and closures have been officially voted into C++0x! This is really going to make taking advantage of the Standard Algorithms much more straightforward.
Here's a little taste from Herb's post:

In C++0x, you can just write:
// Calling find_if using a lambda, in C++0x:
find_if( w.begin(), w.end(),
[]( const Widget& w ) -> bool { w.Weight() > 100; } );

Yes, you can already achieve the same thing today, with a standard binary predicate and a helper, thusly:

find_if(w.begin(), w.end(), bind2nd(greater<int>(), 100));

but it isn't nearly as easy on the eye, is it?

Lambda functions will also make it a lot easier in situations where now you'd be forced to use a custom predicate; previously you'd have to: create a functor; remember to make it inherit from std::unary_function or std::binary_function for completeness; stick it in an anonymous namespace (optional but recommended; and finally, use it in your invocation of one of the standard algorithms. That works, but if you're coding a for_each, because you're trying to be good and not write a loop on an STL container by hand, then having the interesting part of the loop in a functor makes the code much harder to follow: instead of it being right there in the loop, it has to be somewhere else, breaking up the flow of the logic in the poor reviewer's head.

New Look

As you may have noticed - in the unlikely event that: a) you're reading this at all; and b) you're not reading it in a news reader - that I switched the site from RapidWeaver's built-in iPhone theme to seyDesign's dogPress theme.

I am still not happy with it, but then I can't do web design for toffee, so I'll just have to be okay with the fact that it at least looks a tad better. It's still too narrow, and I had to pants around making the images smaller as the hard edge now makes them look awful when they stick out. RapidWeaver makes this inconceivably (I'll wait for you to reminisce about the Princess Bride here...okay, let's continue) painful. It lulls you into a false sense of security, because it does have a built-in feature to let you scale images, right in its Media Inspector:

RapidWeaver's Media Inspector

Handy, right? Well, the problem is it that if you check "Scale Image" and start modifying the percentage, it does not update the height and width values shown below, or show the new values anywhere else that I could see. My theme has a constrained width for images of about 465 pixels, which I determined from experimentation. If scaling would update the size fields, I could just reduce the percentage until the height showed 465. But, because it doesn't, I have no choice but to disable it and scale the image by hand. So I enter the height of 465 and then determine the new height with 465/original-width*original-height. The only saving grace here is that Spotlight will do basic calculations right in its search window:

Spotlight Calculator

Very handy, but RapidWeaver should not have made me use it in the first place.

RapidWeaver also won't let you preview old blog posts; normally that wouldn't be an issue, but it was for me when trying to find all the images that were too wide for the new theme. I ended up publishing the site as-is then using Safari to walk though it all and find the problem articles.

I picked the blue variant of the dogPress theme and tuned the title and sub-title colours a little. I then used a photograph of The Gateway Arch in Saint Louis to make the header my own. Here's the original shot:

Gateway Arch

I took this in 1992 with my Olympus μ1, a very compact and cool-looking (IMHO) film camera. I held it against the side of the arch pointing up; if you look closely, you'll see the observation windows at the top of the arch in the center of the image.

So whaddya reckon? Less or more ugly than before?

SQLite

We've incorporated SQLite* into a project at work recently. If you haven't come across it before, SQLite is "a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine". Pretty good for a library that weighs in at less than 250KB, huh? It's also trivial to embed, with its amalgamated version (where much of the precompilation is done already) consisting of just one C source file and one header file. There are also wrappers for SQLite's C API available for lots of languages, from PHP to Tcl/Tk; there's even an ODBC driver for it if you're into that sort of thing.

You can use a command line tool to interact with the database, or more commonly, you can integrate the library into your application directly. It's very full featured, with only a few SQL features missing (right outer joins, updatable views, foreign key enforcement, and a couple of other things), so you can perform some pretty powerful operations on your data right out of the box.

Transactions use a journal file, so if power is lost during an update, SQLite will automatically rollback the incomplete transaction when power is resumed. This robustness, couple with its size, makes SQLite very popular with embedded device and cell phone manufacturers. It's used in many cell phones, and it is embedded into Apple Mail and many other common applications, including Firefox.

The implementation of SQLite is pretty interesting, in that it compiles statements to byte code for its own virtual machine when you prepare them. The command line tool even has an EXPLAIN command that lets you see the byte code that a statement will generate, so you can see how it will run and potentially do some optimization. The code is well written and well documented. The code base has a 60/40 split between test code and source code and its regression tests have 98% code coverage. I wish I could say that about all of the projects that I've worked on over the years.

Here's some resources if you would like to find out more about SQLite:

- Leo Laporte and Randal Schwartz talked to SQLite's author D. Richard Hipp recently on episode 26 of the FLOSS podcast.

- There is an excellent book on SQLite by Mike Owens. It covers all aspects of SQLite, from its inception to writing extensions for it. There's also a couple of chapters that provide a nice introduction to relational database theory, and SQL. The only bad thing I can say about this book is that its index is next to useless.

- There's also a nice video of D. Richard Hipp presenting "An Introduction to SQLite" at Google in May of 2006:




*Pronounced ess-que-ell-lite according to its author (and he should know).

Firefox 1.0: the NY Times ad

As the release of Firefox 3 draws nearer, I thought it might be fun to look back at the NY Times 2-page advertisement from December 15th, 2004. You can get the full PDF from my site, but here's a couple of smaller shots of it:

Firefox Ad: Page 1

Firefox Ad: Page 2


And, hidden in the piece of land eminating from the fox's nether regions, is my name. Can you spot it?

Firefox Ad: Closeup

In the 3+ years since it was released, Firefox has done amazingly well, sitting at around a 17% market-share right now according to netapplications. It pleases me to see an open source project scale to the level that Firefox has, take on the status quo and do so well. Version 3 Beta 4 looks pretty nice on the Mac too.

MythTV on mac

I repurposed my Pentium 4 HT tower a while back (no more Windows!) to run knoppmyth, a custom Linux distribution for MythTV that makes it as easy as possible to set up a beige box as a PVR. In our house, this box's primary purpose is to record Spongebob Squarepants ad infinitum, with the occasional Daily Show with John Stewart thrown in for the adults. It works great; I don't even have a monitor hooked up to it anymore, just the TV with the Hauppauge 350's IR sensor hot-glued to the front.

MythTV is often used just like this, with a single machine hooked up to a single television or monitor. However, it can also act as a media server for your network, making all the recorded shows, your music files and pictures available to any other machine on your network running the MythTV frontend. So, I was pleased to fine pre-built binaries of the MythTV frontend for OS X over on their wiki. I downloaded one from The Snider Pad and didn't have too much trouble getting it up and running. All I had to do was change the permissions in the MySQL configuration file on the MythTV box to allow non-localhost connections (set bind-address to 0.0.0.0 in /etc/mysql/my.cnf). After that, I could sit on my bed with the MacBook on its 802.11b connection and watch any of the recorded shows, or live TV even, remotely from my MythTV box.

Here's the main menu:

MythTV menu on the MacBook

From there I'm only a couple of clicks from:

A yellow sponge character on MythTV

...wait, that's not the Daily Show...but I haven't seen this episode before...

The Way of the Brew Peg

I've been a software engineer for quite a while now. How long, you ask? Let's just say that the waterfall model was state of the art when I was studying* for my CS degree. Actually, despite it being the title on my business card, I've always been reluctant to refer to myself as an engineer; writing code has always seemed to me more of a creative process, than one of precision as would befit the title "engineer". Code is constrained more by the experience and imagination of its creator, than by such practical considerations as capacitance and resistance that are the realm of an electrical engineer, to whom the title of engineer seems far more apropos.

But that isn't to say that the work days of we code monkeys are entirely devoid of process. I think it is terribly important to learn from the mistakes we've made in the past. We've learned that customers could not reasonably be expected to completely understand up front what it is they wanted a computer program to do; and so, the rather rigid waterfall model fell by the way side. In its stead we now see predominately iterative models, with Agile seemingly leading the charge these days. This is all good progress, barring the odd self-indulgent wallowing in buzzwords that we've seen along the way. Still, I'm not much of one for blind faith when it comes to software development models or design practices; I don't particularly try and follow any given formal method of decomposition during design, or care whether a particular refactoring I just did has a cool name. So what do I do?

I follow The Way of The Brew Peg:

Brew Peg

So what the heck is The Way of the Brew Peg? Well, at work we have a large coffee pot. It is filled often, as you might imagine, but there's a problem: it's very hard to tell, without stooping down and peering between the filter cup and the pot, whether the coffee is still brewing. Hence, there have been many cases of still-pouring coffee making its way onto the counter and floor as one poor caffeine-seeking soul pulls the pot out prematurely. Sure, an upgrade to a fancier coffee pot might have done the trick: had a glaring brew-indicator lamp, or a locking mechanism of some form. And we even have one of the most imposing looking coffee-in-a-teabag-thingies too.

But you know what works great? A plain wooden clothes peg clipped to the handle of the pot. When your sleep-addled brain tells your hand to pick up the pot, your hand spots the impediment in its path and quickly relays caution back to the brain. Those two small pieces of wood held together with a spring have saved you from embarrassment, a potential scalding and some floor cleaning.

The brew peg keeps me grounded. So while I consider the possibility of reuse when defining objects and interfaces, the brew peg stops me from taking that consideration too far, so that the intended purpose - right here, right now - of that object or interface is not compromised by some potentially nonexistent future need. The brew peg is the physical embodiment of practical simplicity; and, it's comforting to have an actual physical mnemonic in my design process to balance the otherwise overwhelming abstractness of it all.**

So when you're writing that next design document, or defining that API, remember the brew peg. It may not have the pizzazz of a YAGNI or a KISS, but will they keep you from burning your hand?


* where by studying, I mean: playing Super Nintendo while watching Neighbours and listening to "Fools Gold 9:53" by The Stone Roses (played at 33 RPM even though it was recorded at 45 RPM)

** which is also why I like woodworking, as awful as I am at it

Can't do web design for toffee

mmm, toffee

I haven't posted in a while because I have been playing with blogging tools. I currently use RapidWeaver, but it bugs me in a Microsoft Word sort of way; well okay, it's nowhere near that annoying, but still an annoyance nonetheless. It just does things the way it wants to, rather than the way I want it to. It's a bit for flexible than iWeb, granted, but its themes are not nearly as pretty, either.

To satisfy my curiosity about what else might work, I set up a couple of Wordpress blogs (one canned, one not), and a Movable Type blog (way not canned) on my webserver. I then downloaded the much-acclaimed MarsEdit 2, a blog publishing application for the Mac. At first it seemed surprisingly bare-bones (although it's not from barebones), but that actually isn't a bad thing; I suppose I just expected it to be flashier based on what I had heard about it. It has an intentionally non-WYSIWG editor, and the developer in me likes that; needs that even. Besides, Gruber uses it, so it has to be good, right? So, I played around with it some more, and I started to really appreciate being able to set up a post the way I wanted it set up.

But part of me still wanted more control. The little developer in my head, who forgets that I can't do web design for toffee, was saying "let's do this using hand-crafted-with-love XHTML and CSS". I got as far as purchasing cssedit, a really great CSS utility from macrabbit software. I love how you can use it to override the style sheets on a site and tweak them live: really neat stuff. But as I said, I can't do web design for toffee, or any other highly-sugared sweet for that matter (and if you know me, you know how much I like highly-sugared sweets, and hence you know how bad I must be at web design). So, while I have used it to tweak RapidWeaver's themes a little, I haven't really gotten a lot of use from it.

I considered looking at Panic's Coda again. Coda is billed on Panic's site as "one window web development"; it includes a text editor, CSS editor and a cut-down version of Transmit - Panic's excellent FTP/SFTP/etc tool (which I use often). I played with Coda back when it came out, but I didn't care to learn another text editor (it uses SubEthaEdit); and, as I mentioned before, I can't do web design for toffee, so creating the CSS from scratch likely wasn't going to work out well for any passing viewers' eye balls or sensibilities.

So what to do? I think I could get either Wordpress or Movable Type to look the way I want, or as close to it as my can't-do-web-design-for-toffee skillz will allow (thank you, cssedit). I would then have to figure out how to get all the old posts out of Rapid Weaver. It stores your site's data in a single binary project file, so there doesn't appear to be an easy way to extract the individual posts. I could try and scrape the appropriate tags out of the rendered HTML but that seems kludgy at best. Maybe if I create a RapidWeaver them that has next to no formatting and publish that, the scraping might be easier?

As I continue to ponder, I will stick with RapidWeaver. Maybe version 4 will make me okay with staying the course?