Why you’re wrong if you think spaces are better than tabs

OK, time to finally throw my hat into the political ring.

But I want to state for the record as a disclaimer that I do so not based on opinion, but merely based on the facts:

Tabs are better than spaces.

Now, quiet, you python people. You’re just wrong. I know that your style guide PEP says you should use 4 spaces.

But it’s wrong.

Now, you’ve all heard the old unix greybeard argument about how your files will be 2% smaller if you switch to tabs instead of spaces, because you’ll use 1 tab character rather than 4 space characters. While this argument is correct, it has nothing to do with my argument (it’s just another benefit of using tabs, as far as I’m concerned). But a small saving in file size isn’t a reason to change how you do things.

The reason you should change how you do things and start using tabs instead of spaces is simple: it’s the correct answer. But that’s not actually my primary reason. My primary reason is that it’s better.

Now, this might sound arrogant or whatever, but allow me to explain what’s actually going on under the hood, and how you can configure your editor correctly and we can all live in peace and harmony and never worry about this whole indentation thing ever again.

A lengthy treatise about the history of text (and how it’s indented)

A long long time ago – even before Nirvana – there were mechanical typewriters. That’s where the tab key comes from, since our computer systems were originally used with teletypes, which were based on typewriters.

But typewriters didn’t just have a tab key – they also had tab stops – a bar along the back of the typewriter with several movable latches which allowed you to set the tabs at any position you like. The behaviour of the tab key and tab stops in a WYSIWYG word processor emulates this pretty faithfully (though it is a superset of typewriter functionality, e.g typewriters had a limited number of tab stops and afaik could only do left-aligned tab stops).

When we started using teletypes and terminals, we were originally using fixed-width (i.e the screen was typically 80 or sometimes 40 characters wide, and used a monospaced font) text-only monochrome displays. And back in the 60s IIRC the ASCII standard was developed as a descendant of the baudot code used on telegraphs.

This standard defines a bunch of characters, and a bunch of control characters. If you’re familiar with ASCII or unicode at all you’ll recognise some of them. Some common examples:
character 32* – space
character 10 – linefeed
character 13 – carriage return
and character 65 – an uppercase “A”.

(* i tend to think in decimal, these are decimal values. All ascii values here should be decimal for consistency)

If you’ve ever played with colours in your terminal prompt, you might also recognise escape as character 27.

There are a bunch of these available, and you can see the full list with a simple ‘man ascii’ (assuming you have the relevant packages installed, apt-get install man-pages should do it on debian).

In this table, we see my beloved tab sitting at position 9. And you’ll also see one that you probably haven’t used before – character 11 – “vertical tab”.

All of these things are there for a reason, even though we almost never use some of them (like vertical tab) today.

There are a few intricacies of the ascii table which aren’t mentioned or immediately obvious from reading the man page I pointed you to. They’re a little more obvious if you look at a 4-column ascii table with the hex and binary values (<-- I'd encourage you to open that in a new window so you can look at it while reading this lengthy tome).

With this layout, it becomes more obvious that the first 32 ascii characters are in a special class that you probably already know about - these are the control characters. There is one other control character which is outside of this range and a special case - 127 / DEL.

Less Obvious is that this pattern of categorising the ascii table into sets of 32 applies for all four columns. The ASCII table was intended to be broken up this way: WE have four broad categories of characters here: control characters, symbols and numbers, uppercase, and lowercase.

Note another correspondence when we break the ascii table up in this way: the lower word (i.e the last 4 binary digits) are the same for each character for both uppercase and lowercase - we can think of the upper word / first four bits* as a "mode selector" to select between columns on this table, and the lower word selects one of the rows, giving a particular character.

(* in reality it's only three bits in the upper / most significant word, because we're only talking about 7-bit "pure" ascii today, but I'll be referring to them as two 4-bit words here to make things clearer - the most significant bit is always 0 for our purposes today)

This idea is modelled on an earlier code (baudot? something else? the history is long) and is in turn modelled on typewriters and how the shift key worked: On a mechanical typewriter, the shift key worked by physically shifting the printing mechanism or head (versions differed), and each "letter-stamper-thingy" on the typewriter had two characters - uppercase and lowercase (the names of which in turn come from a printing press operator's two cases of letters - uppercase tended to be used less often, so the operator would place it in the upper position, further away from his working area) - and depending on the position of the shift mechanism, selected between the two characters, giving each normal key two functions. Similarly, the number keys had symbols as their "uppercase character".

This design characteristic makes it pretty easy electronically to implement this "shift" mechanism for most of the keys on your keyboard without any special logic to handle upper/lowercase - each key has an encoded 4-bit value, and depending on the state of the shift key we set or unset bit 3 of the upper word (it's a little more complex than this these days, e.g capslock).

And that's why teletypes were fairly common already by the time computers were invented - they're a lot simpler - the character table is designed to make it easy electronically.

But it doesn't stop at the keyboard, it's also easier to interpret on the decoding end: if your bit 3 is set, you want to select a lowercase glyph. This is a very easy test that can be done with few logic gates, and in very few instructions on most(all?) computer processors.

So this meant that when computers came around, and we wanted a system to have them represent text and interact with keyboards, adopting this table made a lot of sense due to the slow speed of those early machines - efficiency was everything. And so ASCII was born - people took clever ideas of their predecessors and expanded on them.

You'll also notice that in this layout, the symbol characters between the uppercase and lowercase and at values >=123 make more sense – if you’ve ever looked at an ascii chart and wondered why e.g the symbols or letters weren’t all in one contiguous region, this is why!

(Today, we’re not technically using ASCII anymore – these days, all modern operating systems use unicode. But unicode takes this compatibility thing that ascii did even further – you may know that unicode is byte-compatible with 7-bit ascii, so a pure ascii file (and most english text from other similar encodings, e.g iso-8859-1, too) is also a valid, identical unicode file)

So far we’ve only covered columns 2-4, but a simple glance at our ascii table shows that column 1 is special. And you already know why: none of these are printable characters – except, debatably, tab.

You probably know about nonprintable characters – unicode means that most computers have lots and lots of them today. But you might not know the distinction between a printable / nonprintable character and a control character. And that’s what this column actually is – these are the control characters, not the nonprintable characters.

There is one other control character – DEL – which doesn’t live in this column. I’m not sure where it’s position at the end of the table originated and how that decision came about. But this is also relatively easy to test electronically – a 7-way AND gate on your 7 bits, and in code. Putting it at the end of the table like that makes it a relatively simple exception that you need to accommodate.

They’re control characters because this encoding was invented to provide all the functionality of all the various teletype machines out there, providing “one encoding to rule them all”, which should be able to work with any teletype, providing interoperability.

Teletype machines needed to have a way to signal to each other that this should be the end of the line, for example, and so you have a linefeed character. Today you might think of a linefeed as “just another character”, but the term “control character” isn’t just a pretty name – in it’s original intent, “linefeed” is not a character but an in-stream instruction for the receiving device, which means “move the physical roller which controls the vertical position of the physical paper in the actual real world one line down”. Presumably on some teletypes it also meant “…and return the physical IRL print head to the first column”, and on some it didn’t. In order to support all the features of all the teletype machines out there, a bunch of control characters were needed.

No, I have no idea what half of them do, either.

I do know about a couple that you may not have heard of. For instance, there’s the one that I call “EOF” – end of file, but which the ascii table lists as “End Of Transmission”, at position 4. Unix implements this as it’s “End Of File” character – this is what your terminal sends down the line when you press CTRL-D. It’s why you can press CTRL-D to log out of your terminal. It’s also why you can do

$ cat - > /tmp/foo (enter)
$ cat /tmp/foo

to create a file which includes linefeeds from the unix prompt, using cat to read from stdin and then using ctrl-d to send the the end-of-file character to tell the system that you’re done inputting data.

A more commonly known one due to a decision by microsoft to be contrarian is the difference between a linefeed (“move 1 line down”) and a carriage return (“return the carriage (or cursor) back to column 1″). Technically microsoft’s preference of doing both a carriage return and linefeed is perhaps more historically accurate, since in almost all cases you would want to do both of these things when the enter/return key is pressed, whereas unix says that a linefeed implies a carriage return, and interprets carriage return as “*only* do a carriage return, not a linefeed”, meaning that on unix CR allows you to “echo over” the same line again, and that means you can draw bar charts in bash using echo -e “\r$barchart” in a loop.

I member a time when *nix used LF, Windows used CR + LF, and macs used CR just to be totally goddamn annoying. Apple adopted LF along with unix with the advent of Mac OS X, so that’s not a thing anymore unless you’re into retrocomputing.

You may have seen the good old ^H^H^H^H^H^H joke, where a person is deleting their code. This is because the backspace character/key at position 8 was traditionally mapped to CTRL-H, which could render on some terminals visibly as ^H rather than a backspace depending on a ton of hardware variations and compatibility settings on the terminal you were sitting at and the terminal you were talking to.

CTRL-L clears the screen on *nix because it’s mapped to the form feed character at position 12. Likewise CTRL-C is mapped to character 3 (end of text, i’ve always called it ‘interrupt’). I believe that the dreaded CTRL-S and CTRL-Q to freeze/unfreeze output on your terminal are mapped to control characters, too, but I couldn’t tell you which ones.

There’s also a fun one which doesn’t appear to be mapped on my modern linux machine – CTRL-G, to ring the terminal bell.

These control key sequences exist because when people started using different terminals to talk to unix systems, they quickly found that not all terminals were the same. E.g not all of them had a ‘backspace’ or a ‘clear screen’ key, but all of them had some kind of “control” or “modifier” key, so the control sequences were added for people who didn’t have the corresponding key. To this day, I have a ‘compatibility’ tab in my terminal which allows me to tell the terminal to send a CTRL-H key sequence for backspace, amongst other things.

A short aside:

As I’ve demonstrated above, one of the pitfalls that we find ourselves running into on modern unix systems is that by the time you get to a terminal emulator in your gpu-accelerated, composited GUI, you’re running many layers of abstraction and compatibility deep: Your terminal is emulating and backwards-compatible with VT100 dumb-terminal hardware from perhaps the 1970s, patched to be able to support unicode, which is itself a backwards-compatible extension on top of the backwards-compatible extension of a previous code that is ascii, going all the way back to bardot and the telegraph in the late 1800s. So, no, it’s not as straightforward as you’d expect to write code to say “move the cursor to position x,y” on a unix console.

This causes us a bunch of problems and causes us limitations on modern desktop unix systems perhaps more often than it helps the average user. If you read the unix-hater’s handbook, you’ll find an entire chapter on how /dev/tty and the terminal emulator is the worst thing in the entire universe. This is generally acknowledged as one of unix’s “foibles”.

So why hasn’t anyone done anything about all that legacy stuff?

Because one of the joys and beauties of unix is the deeply-ingrained principles of backwards compatibility and portability that came to embody the unix philosophy over the course of decades. Which means that I can still (relatively) easily connect my modern terminal emulator up to an antique teletype and have it be compatible to a pretty decent extent.

This is an important quality of unix. It’s important to keep these open, compatible standards around for the purpose of the preservation of information. If we had moved from ascii to an incompatible standard, we would have had to convert every single document ever written in ascii into that new standard, or potentially lose the information as the old and incompatible ascii standard became more and more rare and unknown.

And if you search youtube, you can find people hooking modern systems up to antique teletypes. For my money that makes it all worth it.

But finally, Let’s talk about tab.

Note that space is up at position 32, in column 2 with the printable characters. I’ve seen space categorised as a nonprintable character, but this is the wrong way of thinking about it. A better way is to think of space as a fully black glyph on an oldschool fixed-width text terminal (regardless of whether or not it was actually implemented this way). You want a space character to erase any pre-existing character at that position on the screen, for example. And you want that “move on to the next screen column with each keypress, so that the user can type left-to-right” functionality that you get from making it a fully-black glyph.

For example, in bash:

echo -e "12345 \r     67890"

doesn’t give you the output:


it gives you:


- the spaces erase the previously-printed characters.

Space is a printable character.

Tab is a control character.

I was tempted to write “which means ‘print 4 spaces’ on my system”, but I thought I’d do another bash example/test/demonstration, and I surprised even myself. On my system, it’s not “print 4 spaces” at all:

$ echo -e "1234567890\r\tABCDEF"

I had expected this to echo


But it turns out that the implementation of tab on my system is a bit more complicated than that. Instead it means “indent by one tab width”. If I did:

$ tabs -8
$ echo -e "1234567890\r\tABCDEF"

I’d get:


And if I do:

$echo -e "\tsomething"

That’s not 4 spaces that it’s printed at the start of the line – try selecting that text – it’s a single tab character, and its width is whatever your tab width is set to (since it’s being displayed on your machine right now).

I think this demonstrates pretty clearly that space is printable and tab is control :)

When fixed-with, monochrome teletypes and terminals were the norm (and for a long time they were the best way for humans to talk to computers – they beat the shit out of punchcards), and the ascii standard was adopted for use on a screen – with generally more capability than a teletype (a screen can easily delete characters / clear itself, and can emulate an infinite roll of paper by scrolling lines), indentation came up. This caused an issue at the time because they didn’t have WYSIWYG word processors with an infinite number of center-aligned tabs that could do everything your typewriter could do. Instead, they had this atomic system – there was no physical way on these devices to have a ‘half-character-width’ tab, like you could on a typewriter. And not a lot of memory or processor power for implementing fancy rules around kiiiiinda-trivial stuff like tabs. So the compromise that was reached was making a tab equal to a certain number of spaces.

But how many spaces? Some said 4, I think some said 8, and some said 2. This is what the ‘tab width’ setting of your text editor means. I’m sure others did more complex things with tab, like “indent to the same column as the next word from the line above”.

I’m not sure where the convention of “a tab equals 4 spaces” came from, but that’s certainly the one that became dominant at some point. Maybe it’s standardised somewhere, maybe it’s just a popular convention.

The point is, the way that tabs was handled used to differ at one point between different terminal hardware and/or settings. This is why tab settings are so seemingly-complicated in plaintext editors today – Similarly to why ASCII has so many control characters, terminal emulators wanted to be able to emulate multiple types of terminal, so the tab settings had to be a superset of all of them.

The practical upshot of all this means that by correctly using your IDE’s “Tab width” setting, if you use tabs for indentation, you don’t need to have this argument about whether a tab should be 2 or 4 or 8 or 32 spaces: You simply set the tab width to your preference and tell your IDE to use tabs for indentation, and you’re set, and can see it indented however you like, and so can everybody else. We can all just use tabs correctly, and live in peace and tolerate each other’s preferences for indenting.

(The correct IDE settings are: Tab width: whatever you prefer; Use tabs for indentation, never spaces; aggressively and automatically convert groups of spaces *at the start of the line* into tabs. Auto-indent. If your editor can’t do these things, you should use a better one. Scite and Geany are good).

And there are valid preferences, too – I personally use 4 spaces indents on a desktop or laptop machine where characters are small and screen real estate is cheap, but if you’re coding on a small form-factor device with a small screen that can’t display long lines easily and large enough to be readable (like my openpandora), an indent of 2 characters is much more workable.

Another still valid though less-relevant-today reason to have a preference about tab width is something i only touched on very briefly earlier – some of these fixed-width displays were 40 columns, and some were 80 columns. The most common 40 column displays you would see were on the 8-bit microcomputers of the 80s, which tended to be built to hook up to TVs via an RF modulator, typically leading to insufficient resolution to do 80 columns and be readable. On a 40 column device there’s a good argument for a smaller indent for the same reason as I have on my openpandora – screen real estate.

So to start summing this all up and getting back to my original point, and although I’ve spent a million words describing the “why it’s more technically and semantically correct”, my #1 argument for tabs is not even based on any principle of it being more technically or semantically correct, or respecting the past, or anything like that.

I argue for tabs over spaces for indentation based on features: Done correctly, it removes the whole “How wide should an indent be?” question and allows users to decide based on their preference while still working together and having consistent code.

But I do also argue for it based on a nerdy “technical correctness” and “compliance with well-reasoned specifications” principles, too: In python, tab is even more explicitly semantically correct – in python we use indentation to signal a block of code to the interpreter. That’s the job of a control character, not of a printable character. That’s exactly what control characters are designed for. Those smart guys back in the 1960s or 1910s or whenever it was knew what they were doing when they put space in there with all the other printable characters.

However, note that when I say that you should be using tabs for indentation, I do not mean they should also be used for formatting – that does cause issues, as many advocates of space have pointed out in the past. I think maybe this is the most common pitfall is that people run into which makes them prefer spaces. But understanding these tab settings is not hard, and there’s a benefit for all users, and it’s the correct option, and also it saves you some space, because one tab character is one quarter the size of 4 space characters!*

(* this old argument for tabs is actually not really true anymore a lot of the time: if you’re transferring this as plaintext over http, you’re probably using a modern web browser which supports http2 and/or gzip compression, and it’s quite likely you’re talking to a server that also supports it, so there’s a very good chance that you’re getting those 4 space characters gzipped, even if you’re not minifying your javascript, and in that case those 4 tabs will take up perhaps 10 or 11 bits of data vs the 8 bits a tab would use )

So, for example:

#!/usr/bin/env python3

def something():
	# this line is indented. You should use a single tab character to indent it.
	#    but if I want to indent this line inside the comment, this is formatting, 
	#    and I shouldn't use tab for that.
	#<-- tab
	#    <-- spaces      
	# so, for example, to make an ascii-art table outlining the characters on this line:
	#    ----
	# it would be:
	#  pos | character
	# -----------------
	#   1  | tab
	#   2  | hash
	#   3  | space
	#   4  | space
	#   5  | space
	#   6  | space
	#   7  | hyphen
	#   8  | hyphen
	#   9  | hyphen
	#   10 | hyphen        # note consistent column widths here, 10 is longer than 9, 
	#                      #   don't use tabs here between the hash and pipe characters


In the code world I've found that this formatting rule boils down to a pretty simple generalisation: left of the comment signifier (the hash character in python), that's indentation, right of it is formatting.

(yes, there are always weird edge cases, like heredocs, where formatting and indentation simply cannot be done well and unambiguously, but I've found this system to work pretty well. In these cases you should do what seems best and cleanest)

And now hopefully you know why tabs are correct and spaces are wrong. Please feel free to disagree and argue that the PEP says so, but just know advance that if you do that you will be wrong.

More seriously, I would welcome discussion over some of the edge cases and pitfalls that people can run into with regard to this stuff. I find that a lot of the issues that people complain about with tabs also occur with spaces. It'd be cool to put together an exhaustive resource on the subject to document what is totally the empirically correct way to do it.

If you made it through this may thousand rambling words over something that many would consider trivial, thanks for reading :)

This site requires IE6

Welcome to the new and wonderful world of the “modern” web, where you can be running a browser released 2 months ago and it’s considered OK to not support it because it’s not one of the big three.

I particularly adore the fearmongering security theatre used as an excuse for their not bothering with progressive enhancement and compatibility.

Now, I suppose to be fair I should concede that although I do label it as a “blatant lie”, it is possible that I might be wrong and this might not actually be a lie: It could just be that they’re simply incompetent at web development.

983 days uptime

bye bye hactar. You were a good server. It’s a pity we didn’t quite make it to 1000 days.

(the machine was decommissioned today by people who aren’t me. Interestingly, this action immediately caused a website outage. I’ll refrain from any more blatant “I told you so”‘s).

The State of Pulseaudio in 2021

Every now and then I like to revisit an old topic.

So, let’s revisit pulseaudio and my hatred for it, shall we?

Now, you’re not an old greybeard like me, so you’re probably saying to yourself right now “OMG still with pulseaudio?!? That attitude is sooooo 2008!”

Well, for all the people over the years who have repeated the line of pure bullshit propaganda that “pulseaudio is much better these days and almost sorta kinda works most of the time, if you squint”, I’d like to present my first, reflexive solution to the fact that today I had no audio in zoom on a laptop with a current version of pulseaudio. A solution which, I might add, solved my problem instantly:

$ sudo bash -c "while true; do pkill -9 pulseaudio; done" &

Sure, it might not be efficient or pretty, but it worked. And it serves as a perfect metaphor for the state of Linux audio for this past decade and change, which can be summed up as “If you have an audio problem on Linux, the fault lies with pulseaudio”.

There have been multiple occasions where I’ve been trying to figure out some weird audio behaviour, only to realise “Oh OF COURSE! How silly of me! this machine has pulseaudio installed!”, and disable pulseaudio, and the problem goes away.

I’d file bugs for all this stuff, but I’m sure the fault lies with gnome (which I don’t use), or KDE (which I don’t use), or nginx, or my distro, or perhaps Microsoft Office. I’m sure these things are not actually problems with pulseaudio, because Lennart’s software never has any bugs.

I for one welcome the next decade’s worth of “if there’s a weird issue on Linux, The problem lies with systemd”, and being told in my bug reports that the problem is in the default configuration that comes with Mac OS X Server.

Now it’s off to go read the documentation (yet again) on how to disable this godawful dreck to stop it from automatically starting itself. Unfortunately we’re not in the days where just removing it is a simple option anymore (thanks for the totally unnecessary hard dependency, mozilla!)

RIP John McAfee

John McAfee has been found dead in his cell hours after a court ruled he would be extradited to the US.

The article says “Authorities said the cause of death was being investigated”.

For once, I agree wholeheartedly with the Authorities. It sure was. Though I find it surprising that they would make such a candid admission.

Luckily, his important advice on how to uninstall McAfee Antivirus will be with us forever:

Say what you like about the man, but he was always entertaining.

Bye bye github

Microsoft announces the ruination of github.

Because apparently destroying skype, linkedin, hotmail, etc etc etc wasn’t enough.

I can’t fathom the rationale behind this. Apparently there’s an accounting thing that having lots of users means you’re worth lots of money. So, 7.5 billion.

BUT surely there’s nobody out there who doesn’t think that MS buying github will immediately lead to an exodus of most of its users? As far as I’m concerned it’s a given: MS buys github, github users leave en-masse. I know it’s what I’ll be doing.

So basically MS is buying a website which will no longer have any users for 7.5 billion. Good luck with that.

I’d find it funny if it wasn’t so tragic. I liked github. Just like I liked skype.

Apple knows best

A paraphrased version of a funny conversation I had once via SMS:

Me: “OMFG I simply cannot grok the iphone interface, it’s completely awful on so many levels. If I was going to go into detail I’d need a proper keyboard to type up the relevant hundred-thousand word thesis – even this phone’s physical keyboard has its limitations.”

Smartass iphone user: “What is ‘grok’? If you had an iphone, autocorrect would have picked that up for you.”

Me: “Yeah? Well autocorrect would have been wrong – type ‘define grok’ into a search engine.”

Iphone user: “…Oh.”

Me: “lol, pwnd.”

Future History of Init Systems

  • 2015: systemd becomes default boot manager in debian.
  • 2017: “complete, from-scratch rewrite”. In order to not have to maintain backwards compatibility, project is renamed to system-e.
  • 2019: debut of systemf, absorbtion of other projects including alsa, pulseaudio, xorg, GTK, and opengl.
  • 2021: systemg maintainers make the controversial decision to absorb The Internet Archive. Systemh created as a fork without Internet Archive.
  • 2022: systemi, a fork of systemf focusing on reliability and minimalism becomes default debian init system.
  • 2028: systemj, a complete, from-scratch rewrite is controversial for trying to reintroduce binary logging. Consensus is against the systemj devs as sysadmins remember the great systemd logging bug of 2017 unkindly. Systemj project is eventually abandoned.
  • 2029: systemk codebase used as basis for a military project to create a strong AI, known as “project skynet”. Software behaves paradoxically and project is terminated.
  • 2033: systeml – “system lean” – a “back to basics”, from-scratch rewrite, takes off on several server platforms, boasting increased reliability. systemm, “system mean”, a fork, used in security-focused distros.
  • 2117: critical bug discovered in the long-abandoned but critical and ubiquitous system-r project. A new project, system-s, is announced to address shortcomings in the hundred-year-old codebase. A from-scratch rewrite begins.
  • 2142: systemu project, based on a derivative of systemk, introduces “Artificially intelligent init system which will shave 0.25 seconds off your boot time and absolutely definitely will not subjugate humanity”. Millions die. The survivors declare “thou shalt not make an init system in the likeness of the human mind” as their highest law.
  • 2147: systemv – a collection of shell scripts written around a very simple and reliable PID 1 introduced, based on the brand new religious doctrines of “keep it simple, stupid” and “do one thing, and do it well”. People’s computers start working properly again, something few living people can remember. Wyld Stallyns release their 94th album. Everybody lives in peace and harmony.


I have fortune integrated into various scripts. Because I can.

Today, logwatch gave me one that made me chuckle:


This otherwise unremarkable language is distinguished by the absence of
an “S” in its character set; users must substitute “TH”. LITHP is said
to be useful in protheththing lithtth.

HOWTO: Power on your computer

In this latest entry in my series of helpful ‘how to’ articles, I’ll be teaching you how to power on your computer.

If you have a PC, follow these steps:
1. Ensure that the machine is plugged in
2. Ensure that the rear power switch is in the ‘on’ position
3. Press the ‘Power’ button on the front of the device.

If you have a mac, these are the steps you’ll need to follow:
1. Ensure that the machine is plugged in
2. Examine the machine, noting that there’s no power switch anywhere to be seen.
3. Unplug all cables from the machine
4. Pick up the machine and examine it from every angle, looking for the power switch. You’ll note that it’s in a location which is completely nonfunctional and unintuitive. But at least it doesn’t interfere with the nice brushed metal finish.
5. grab a permanent marker and put a mark on the front of the machine (preferably on the lovely brushed metal) where the power switch is, so that it’s possible to turn it on again without repeating this entire process.
6. Put machine back on desk
7. Plug all cables back in
8. Reach around and behind the monitor, through all the cables you just plugged in, and press the power switch
9. Kill yourself.

The biggest problem with Microsoft certification

The problems with Microsoft certification are myriad.

One really big problem is that people with Microsoft certification think that because they know how to use the Wizard provided by Exchange server, they know something about email, the internet, or networking.

Microsoft certification teaches you the practical knowledge you’ll need to run a variety of servers – on Microsoft tech. You’ll be able to do cool things fast – as long as Microsoft anticipated that need. And you’re basically taught a mantra that says that if it doesn’t have a Microsoft logo, it’s “Not Compatible”.

In reality, the opposite is true: Pretty much everything is compatible, except for Microsoft. And usually everything is compatible with Microsoft, despite their best efforts to embrace and extend. The only thing is not compatible is that Microsoft products aren’t compatible with non-microsoft products.

But I think perhaps the biggest problem with Microsoft certification is that when people finish their course, they get a shiny certificate, and it says that they’re Microsoft certified. And Microsoft people spend lots of time impressing how respectable they are on their customers. So people get this impression that their Microsoft certification means that they deserve some kind of respect.

Firefox Demographics

Dear Firefox devs,

I’ve been using your browser for 10 years or so now – ever since I started to learn about open source software. The difference from IE was amazing – tabs!

Later, the difference became even more profound – Adblock! Firebug! and too many other add-ons to mention – eventually it got to the point where I had to limit the addons I use in order to not clutter and slow things down. Firefox really was the browser for power users.

I had my complaints – the CPU usage always seemed too high, and the memory usage was particularly absurd, but it did everything well.

Chrome happened. It closed the gap somewhat with its built-in developer tools and extensions. The one-process-per-tab idea was a good one. It was fast, and it didn’t require a gigabyte of memory to display one tab, but it just didn’t have the flexibility of firefox, so I could never quite make the switch.

There was one other thing about chrome I didn’t like – it had that sleek, minimalistic, “modern” interface. You know the type: they have pretty curved edges and nice animations for everything, but they tend to not be very configurable.

So it was with sadness that I updated my system the other day, only to see a shiny, chrome-lookalike interface on firefox.

I spent ages trying to turn the add-on bar back on and to remove the button which shows the awful new menu, to no avail.

Eventually I found the classic theme restorer add-on, which makes things sane again, but it’s not exactly awesome: Firefox is now using even more memory and I have yet another add-on installed just so that the interface isn’t terrible.

It seems that firefox is going for a new target demographic: they’ve decided to abandon the power users and go after the crowd who like chrome but think that it’s just too fast and doesn’t use enough memory.

Maybe they could use a new slogan: “Firefox: it’s just like chrome, only slower!”.

Personally, I think that this new demographic might be a limited market. If I wanted to use chrome, I’d…uh… use chrome.

Meanwhile, I wonder what the Opera team have been up to gor the last 5 years…

The Neo Freerunner – A Review

I just emailled this to some guy who was asking about the freerunner on the openmoko lists, where I still lurk. I was proofreading it and thought to myself “hey, this is actually a pretty decent review of the device”. So here it is for all to see:

The freerunner is the worst phone ever made. It might nearly be usable as a phone now thanks to Radek and QTMoko, but you’re much better off buying an old feature phone or rooting an android phone. I think that while it might nearly be acceptable for a linux hacker, the freerunner software will never be a truly good user experience despite radek’s efforts – it’s too big a job for one person. I hope I’m wrong about that, but I don’t think I will be.

I was particularly appalled at the battery life. The battery used to last about 2 hours, but they have nearly solved all the power management bugs so if you’re lucky you might get ~6 hours out of it these days. It might even last all day if you keep it in suspend and don’t use it. In particular, using Wifi, Bluetooth, GPS, or having the screen on will significantly reduce the battery life you should expect to get.

It doesn’t have a camera, though I believe there’s a camera module for the GTA04.

An important thing to note is that due to a design flaw, the device is not capable of fully utilizing it’s accelerated graphics as bandwidth to the screen is limited. therefors it’s not capable of playing fullscreen video at the native resolution of 480×640. It will play fullscreen video if you’re into extremely crap resolution – 240×320. You shouldn’t ever expect to see much more than 10-15fps at full resolution.

The company went out of business because they made a buggy phone and couldn’t figure out what they wanted to do software-wise – they seemed to think that making the UI themeable was more important than being able to recieve phone calls or have working power management. The demise of Openmoko is a good thing.

If you’re looking for a phone, you do not want a freerunner.

If you’re looking for a hackable linux palmtop with a tiny screen, no keyboard, not very much power and a fairly awful battery life when you’re using it as a computer, then the freerunner might be an option for you, although you can probably buy something like a raspberry pi with 3 times the power for half as much money.

Nikolaus’ GTA04 project does seem much more promising and addresses a lot of the shortcomings of the freerunner and may be worth looking into. I have spoken to Nikolaus via email a few times and he seems like a very cool guy – I trust him and I’d buy a GTA04 in a heartbeat if I wasn’t put off by the price – I already spent $400 on a phone that doesn’t work, and I bought a nokia so that I’d have a working phone before Nick brought out the GTA04, so I can’t justify spending that much money to make my freerunner useful.

Spilt Milk and the Model M

Aah. how I love my Model M. I’ve written about it before. The click-click every time I press a key. It feels like I’m accomplishing something. I do this wierd hybrid two-finger/semi-touch typing technique from which I can’t seem to break the habit, but touch-typing is easier on the Model M for me – the keys have sharper edges and are therefore more distinct to the touch – my fingers just seem to fall into place. The other thing I love about my particular Model M is that it’s extra-awesome: it has a manufacture date in 1992 stamped on the back, and a real proper motherfucking IBM logo on the front – none of this modern USB stuff. It’s a real proper original IBM Model M, though 1992 is getting kinda late for original – it’s “only” 21 years old.

The Model M really is an example of engineering at it’s best: In this way it has something in common with Commodore hardware – they’re from the same era, and every commodore machine I have which wasn’t spare parts when I got it still works. Some of the ones I got as spare parts aren’t spare parts anymore – they’ve been turned back into working machines. My Amiga 2000 is one of my most treasured posessions. I hardly ever use it. But when I turn it on, it just works… For twenty years! It’ll still be going long after this Dual Core 3ghz lintel box I’m using now is dead. This stuff is designed to last, no planned obsolescence here! Can you imagine the testing these things went through? Automated machines pressing those buckling springs over and over again to find their point of failure. I don’t even know what it is but I’d bet they’re rated for millions of keystrokes. Per key. This is not a flimsy piece of junk which falls off your lap and breaks, though it could maybe break your toe if it lands on it. Old cars are like this too – they’re designed to last a lifetime. Barring violent destruction at the hands of nefarious third parties my Model M is the last keyboard I’ll ever need.

I’ve hardly used it in 2 years. It was plugged into a server went pop a few months ago which I haven’t bothered to resurrect. The server used to be my primary machine before I got my current primary machine. It has it’s own new-fangled USB wireless non-Model-M keyboard with permanent ink blotting out the awful logo on the ‘super’ key. I use this new machine for games since it has a nice nvidia card and I’ve found that the Model M isn’t the ideal gamers keyboard for action games – the only shortcoming I’ve discovered – those ultra-tough keys aren’t designed for being pressed in rapid succession. Or, perhaps more accurately, my fingers lack the dexterity to press the same clicky-style key quickly enough. So I’d never bothered to plug in the good old Model M, even after the old server died.

Enter spilt milk leading to a sticking tab key. Uber annoying im vim. The story should be pretty obvious from here – no more fear of spilt milk, certainly no crying over it…

…except for one detail: now I have a good, PS2, Model-M keyboard with it’s awesome 2-3 metre cable and it’s clicky keys and weight (it really feels like a piece of furniture sitting on your lap!), AND a mere wireless USB keyboard with noobish easy-to-press keys that are nice for gaming. Awesome. :)

Things aren’t moving backwards

No, things aren’t moving backwards at all!

Let’s look at some of the awesome new features of a couple of current-gen Microsoft products:

Windows 7: One of my FAVOURITE features is the way it assumes that I, as a user, am too stupid to know how to resize a window: apparently, if I want to move a window mostly off the right-hand side of the screen, what I actually want to do is resize that window so that it takes up half the screen! Apparently I’m too fucking retarded to know that I can achieve the same result by simply moving my mouse to the top-left or bottom-left corner of the window and just resizing it. Of course I’m not sure how it thinks I intended to resize the window, given that the resizing corners at the right are off-screen.

Similarly, if I want to move a window to the top of the screen, that means I want to maximize! Apparently, I’m too fucking retarded to know to just press the maximize button like people have been doing for about 20 years. Apparently, after moving my small scite window to the top of the screen, I planned to use the resize corners to resize it so that it filled the whole screen, rather than just pressing maximize. It’s really great that I have this software to do my thinking for me: I’d been struggling with that whole ‘maximize’ notion for years.

So we’ve established that Microsoft thinks my intelligence lies somewhere between that of Mac user and an inanimate carbon rod.

However, when I want to access the New-And-Improved(TM) ribbon interface and add a button to it programatically via VBA – you know, so that my (retarded) users just get a new button they can click to make things happen, I find that:

(from A Blog Post):

You cannot create ribbon elements dynamically in VBA

It is not possible to create ribbon elements dynamically via code as 
with Office 2003, where you could manage your own CommandBars and 

In Excel 2007 each ribbon element (Tab, Group, Buttons, etc.) needs 
to be defined statically and embedded in the Excel document using a 
specially crafted XML file and with quite a few manual steps, 
including renaming and modifying contents of the Excel document —
factually a ZIP with the XLSM or XLAM extension.


(from This Book):

In previous versions of Excel, it was relatively easy for end users 
to change the user interface. They could create custom toolbars that
contained frequently used commands, and they could even remove menu 
items that they never used. Users could display any number of 
toolbars and move them wherever they liked. Those days are over.
The Quick Access Toolbar (QAT) is the only user-customizable UI 
element in Excel 2007. It's very easy for a user to add a command to 
the QAT, so the command is available no matter which ribbon tab is 
active. The QAT can't be moved, but Microsoft does allow users to 
determine whether the QAT is displayed above or below the ribbon.

The QAT is not part of the object model, so there is nothing you 
can do with it using VBA.

So, to boil it all down, there’s no way for me to programatically add a new toolbar button using this wonderful new interface, which means that my users (who, as previously established, are assumed to be about as clever as sponges) are expected to add a toolbar button themselves by following a set of instructions which I have to put together for them. Never mind the fact that this will inherently create a bunch of issues just in terms of support (e.g: morons calling me up asking what I mean by ‘right-click’ in step 6; users choosing a different icon, or giving the new button a different caption, ruining the uniformity of the interface), how I’m supposed to convey a concept as complex as ‘add a toolbar’ to a retarded grasshopper is strangely ommitted from the documentation I’ve looked through.

No, things aren’t moving backwards at all…

Watch out for the next installment of this series, where we’ll analyse why it’s a good thing to remove features from your program so that the interface isn’t cluttered anymore, because having a complex interface is a terrible, terrible thing, and menus are so unintuitive.

I hear that next year Microsoft is going to help the people at NASA Mission control replace their hideously complex systems (sometimes people have to TYPE THINGS at mission control!) with a (touchscreen) button (with round corners, of course!) that says “Launch Rocket” (in the tooltip, which you can’t see, because it’s a touchscreen – The icon will simply be a cartoony V2 rocket). It’s expected that this will lead to huge efficiency gains in the rocket launching process, and will probably only cause a 20-30% increase in catastrophes.

Routing everything via VPN

I have a VPN.

I have it set up in a pretty standard way: when a machine joins the VPN it effectively becomes part of my LAN. But I don’t route everything via the VPN, that would be inefficient and would waste my bandwidth. I haven’t bothered with doing DNS over VPN, as I usually just use IP addresses anyway (one of the advantages of using a 10.x.x.x network), and when you do that you run into all kinds of complexities and problems (like how to resolve names on the lan you’re connected to)

But sometimes I’m somewhere where I don’t trust the owner of the network that I’m connected to: I don’t want to be spied on.

In these instances, it’s handy to be able to route everything out over the VPN connection.

But if you don’t stop to think for a minute and just try to add a default route which points to the VPN server, you’ll instantly lose your VPN connection and all internet access because there’s no longer any way to reach the VPN you’re trying to route through. Doh.

The solution is simple:

#delete existing default route:
sudo route del default
#traffic to the VPN server goes out via your existing connection:
sudo route add <internet-ip.of.vpn.server> gw <your.existing.untrusted.gateway>
#...and everything else gets routed out via the VPN (assuming your VPN server is
sudo route add default netmask gw

OK, that takes care of routing. Next you need to send your DNS requests out via the VPN, or you’ll still be pretty easily monitorable – overlords will still know every domain you visit. To do that, edit /etc/resolv.conf and change the ‘nameserver’ line to point to the nameserver for your VPN and/or LAN:


I recommend running your VPN on port 443. My reason is really simple: in oppressive environments, you can pretty much count on port 443 being open, since it’s used for https, and https is not something that a tyrannical sysadmin/policymaker can get away with blocking: it’s the backbone of e-commerce. In addition, https traffic is encrypted, as is VPN, so it’s less likely to be monitored by things like deep packet inspection, and any not-too-deep packet inspection is likely to come up with an outcome of ‘encrypted traffic, nothing unusual’ when looking at VPN traffic on port 443.

It should be noted that while this is unlikely to set off automated alarm bells, it will look somewhat unusual to any human observer who notices – your overlords will see a bunch of “https” traffic, but nothing else (not even DNS), which may in itself raise suspicions.

It should also be noted that you very likely just added a couple of hundred milliseconds to your latency and have now effectively limited your available bandwidth somewhat, depending on network conditions.

But I know from experience that the victorian government’s IT agency, Cenitex, is incapable of determining any difference between https traffic and VPN traffic going via port 443.

Though, of course, that doesn’t mean it’s impossible…

…In fact, that doesn’t even mean it’s difficult…

…but you should be reasonably safe from the spying eyes of your microsoft cerfitied sysadmin. :)


“It’s very obvious to me that you don’t understand my question. Can I please talk to someone competent – someone who has some basic knowledge of networking?”

Vodafone Mobile Broadband Technical Support* consultant:
“No, you can’t: We’re an Internet provider, we don’t do networks.”

I was reminded later by a friend that the Internet is in fact a series of tubes. And here I was thinking it was a TCP/IP network. Silly me.

* I use the term “Technical Support” very, very loosely – I do not mean to imply that they provide support or are capable of being technical.

Stallman is Nucking Futs!

Stallman talks about Valve releasing a Steam client for Linux

Go, read. I’ll wait.

Back? Good.

Oh, Look! Valve got a mention by the mighty Stallman!

He asks what good and bad effects can Valve’s release of a Steam client for Linux have? Well, it might boost linux adoption, and that’s good. But…

Nonfree games (like other nonfree programs) are unethical because they deny freedom to their users. If you want freedom, one requisite for it is not having these games on your computer. That much is clear.

Wait, what?

Hang on a minute… If I want freedom, I’m not free to run these games? huh?

IMHO, having freedom means having the freedom to choose to run nonfree software if I want to. I’d rather play Half-Life or Portal than any open source game (It’s not that there are no great open source games, it’s just that Half-Life and Portal are better than all of them).

Stallman goes on to discourage Linux distros from offering the software to users – i.e deb packages for steam, and says:

If you want to promote freedom, please take care not to talk about the availability of these games on GNU/Linux as support for our cause.

Which is totally…fucking…insane.

I’ll be promoting freedom – freedom from Windows: “You don’t need windows anymore – Steam is available for Linux!”. I’ll be promoting the freedom to finally run good games on my chosen OS without any fucking around with wine. I’ll be (gasp) buying a bunch of games. Because a Steam client for Linux would be totally fucking awesome – I think it’d be the biggest event in gaming since Id released the source code for Doom. Just watch the Linux market share grow after the release.

Stallman says that Linux adoption isn’t the primary goal. That the primary goal is to bring freedom to users (But apparently not the freedom to run games they love). But I think that adoption of Linux at this point is more important than sticking to this (silly, BTW: nonfree != evil) principle – The more adoption we see, the more the community will grow, and the better the software will get. While this happens, more people will be exposed to Stallman’s (unrealistic) philosophy.

Stallman does concede that “My guess is that the direct good effect will be bigger than the direct harm”.

Direct harm? Really? I can finally delete that old windows XP partition, and you’re talking about Direct Harm? You think there’s anything at all bad about Valve’s monumental decision to embrace Linux?

You’re fucking crazy. Even distros that your foundation doesn’t endorse (Prepare to be amazed), like Ubuntu, go out of their way to tell the user that they’re about to install nonfree software. It’s always optional. It’s just been made easy because not everybody is as nuts as Stallman – some people, like me, actually want to use nonfree software. I should be free to do that, but apparently that’s not OK with the so-called “Free Software Foundation”. Apparently software should be free, but not people.

(Update: Late 2013: Valve refuse to give me a refund for the nonfunctional game Fez, in violation of Australian Consumer Protection Laws. They try to tell me that the laws don’t apply. I lodge a complaint with the ACCC and stop buying things on Steam. Maybe Stallman isn’t that nuts after all. No company can be trusted.)

(Update 2: 2014: The ACCC Sues Valve for violation of consumer protection laws. I love those guys.)

(Update 3: Jun 2015: Valve announces that they now allow refunds. This is because they’re really good, caring people, and has nothing at all to do with an Australian judge being about to hand out a $10,000/day fine)

(Update 4: comments disabled on this post due to spam bots following the link here from my squee when steam for linux was announced)


Is awesome. This is what Isaac Asimov was talking about… well, not quite, but he’s certainly the best thing we have so far: the form is all there, now we just need a mind.

I’d just assumed he was named for Isaac, but he’s not – ASIMO is an acronym for “Advanced Step in Innovative MObility”. Still, I think Isaac would have shed tears of joy at the sight of him dancing.

I want one.

HP Marketing Techniques

(Originally posted on myspace on 20-Feb-2008)

Update: The only thing worse than a phone running windows? a Neo Freerunner. One day I might post a separate rant about that.

I’ve been using a HP iPAQ 6515 as my phone / mp3 player / GPS navigator / life support system for nearly 2 years now.

It’s a great little unit, in hardware terms – It’s got an SD card slot and a MiniSD slot, meaning you can give it a reasonable amount of storage space for playing MP3s. It’s a Quadband GSM mobile phone, so when I got it my old nokia 6210 got put in the cupboard. It’s got a builtin GPS receiver, and you can run TomTom on it. It’s (barely) powerfull enough to play MP3s and Run TomTom at the same time, which is nice, since I haven’t gotten around to putting a reasonable stereo in my car yet – I haven’t needed to. It’s a PDA, not a SmartPhone, meaning you can run a whole heap of Windows CE applications on it – My favorites are Voice Command, which is brilliant (when you’re in a quiet room, and you don’t have any contacts which sound even remotely similar to each other), and SCUMMVM, a cross-platform SCUMM engine, allowing it to run some of the most classic games ever: I’ve got Maniac Mansion, Indiana Jones and the Fate of Atlantis, and Monkey Island loaded onto mine. Best of all, it has a QWERTY keyboard, which is brilliant for txting – I hate the onscreen keyboards on the majority of PDA-type devices, and I don’t think I could live with a device which can’t atleast have a QWERTY keyboard attached to it.

It doesn’t have too many drawbacks: It lacks builtin Wifi, so I can’t run skype on it – the next model up (the 6965) has Wifi, but I couldn’t really justify spending $800 just for Wifi. You can buy an SD Wifi card for it reasonably cheaply, but the SD slots are in the side of the device, so a Wifi card would stick out the side and present a damage risk when you put it in your pocket (SD wifi cards neccessarily poke out of their slot, as they need space for an antenna, although there are compact ones available which aren’t as bad). It also lacks support for certain bluetooth services, namely high quality Audio – you can’t use stereo bluetooth headphones with it. This is kinda annoying, considering that the bluetooth software which comes with it says it supports high quality Audio. But the wired headset which comes with it is stereo and provides pretty good sound, if not eardrum-burstingly loud. Also the camera on it is not even worth using at 1.3 megapixels, and the HP Photosmart camera software is horrible. It suffices in an emergency, though. Unless the emergency happens at night – the “flash” on the thing is laughable.

Another disadvantage is the godawful Operating system it runs – Windows Mobile 2003SE. It’s slow and horrible – you have to wait a couple of seconds for windows to do it’s thing whenever you take the thing out of standby. And you have to reset it far more often than you’d ever turn a mobile phone off and on. I think that perhaps the slowness it merely related to it not having quite enough memory for my kind of usage – I run alot of programs on it above and beyond the standard Phone and Organiser functionality it provides. Maybe if I was a pleb user and didn’t load software onto it, or if it had more RAM, this wouldn’t be an issue.

I’ve looked into running a real OS on it, but the status of Linux support for this particular devce is not great – I’d probably have to live without access to GPS, the phone functionality may or may not work, the Camera wouldn’t work (pfft), and it could very well take a lot of hacking and mucking about to get linux onto the thing – there doesn’t seem to be any HOWTO for linux on this particular model of Ipaq, and I don’t really have the time and energy to figure it all out, especially considering that this is my phone we’re talking about – a day’s downtime would be unacceptable – I’d need another one to be able to play with to figure out what I’m doing.

but it’s certainly been a good little unit, I’ve thought… so far.

About a month ago, it stopped making noise except through the headset. Obviously what’s happened is that the switch in the headphone jack has become stuck in the ‘headset inserted’ position, which cancels all noise (and microphone input), except for the ringtone, from coming out of the unit’s speaker. I can still use it just fine with the headset plugged in, and I can still use it fine with the headset unplugged, just as long as I don’t want to do anything that requires audio input or output. Like talking on the phone. So at the moment when my phone rings, I have to scramble to find and untangle the headset, plug it in, and press the answer button.

So I contacted HP about this, wanting to know how to go about getting it serviced. I specifically made mention of the fact that this was my primary phone / communication method we’re talking about, so it’s pretty urgent.

I could go through the ensuing catastrophe of customer relations blow-by-blow, but then this would be 800,000 words long, and I would probably end up smashing something. And I’m using a work laptop at the moment, so that’s probably not a great idea. Suffice to say that they take up to a week to even reply to your emails, which you’ve market as urgent, and when they do it’s so unhelpfull that they might have well just kept playing Unreal Tournament, or whatever it is they do most of the time up there, rather than even replying. I just recieved an email yesterday, over a month since our last correspondence, which contained the exact same text as the previous email they sent me. Which I’d already replied to, over a month ago.

HP’s “support” team are without doubt the single most apathetic, indifferent, robotic, unhelpfull bunch of bastards I’ve ever dealt with. and I’ve BEEN an indifferent, unhelpfull tech support bastard before. But I at least used to try to project the appearance of caring about the customer’s problems – after all, it’s the company’s reputation at stake here. But HP’s “support” team doesn’t even seem to care about that.

It seems that HP are trying to sell Nokia products – a brilliant, novel, and innovative marketing strategy if I’ve ever seen one – There’s no amount of money Nokia could spend on advertising (short of having some cute chick giving blowjobs with every Nokia purchased) which would come close to what HP have done in terms of getting me to buy a Nokia handset.

After a couple of weeks of dealing with HP’s completely indifferent “support” team, I decided I’d just find myself an alternative device. It’ll cost me amaybe $1200 extra to do this, but at least I won’t have to deal with these pricks. I wouldn’t know what Nokia’s tech support people are like, because I’ve never had a problem with a Nokia product, ever. And I’ve used a few Nokia devices in my time.

It’s a good thing HP don’t make defibrillators or heart/lung machines.

So, congratulations HP – you’ve managed to ensure that I never buy another HP product as long as I live. You’ve managed to ensure that When I’m reviewing devices at work and making purchasing recommendations (which does happen), I don’t recommend the HP device, regardless of it’s technical specifications. You’ve managed to make the process of finding myself a new device less painfull – anything with a HP logo on it automatically gets excluded from my even looking at it,regardless of it’s capabilities. And most of all, you’ve managed to increase the yearly sales figures of one of your competitors. Whether that’s RIM, Palm, Nokia, Motorola, or somebody else I haven’t yet decided.

Congratulations, HP, and on behalf of Nokia, Motorola, RIM, and Palm: Thanks, HP.