Tuesday, February 19, 2008

Dvorak

Being a geeky programmer, I've grown accustomed to typing dvorak. After 15 years of qwerty my wrists and fingers started to hurt badly (again) and after I saw a new colleague typing dvorak on his (strange, but definately cool) TypeMatrix keyboard, I decided to give dvorak a try. Of course, I couldn't type a single e-mail message in less than 15 minutes, so I gave up before my boss got angry. During the Christmas holidays I practiced dvorak using the online ABCD typing course, and I've since then fully switched to dvorak.

Rearranging the keys on a Macbook
The reason I came to write this blog entry is of course that I rearranged the keys on my Macbook to dvorak. You should be very careful when attempting to do this, as the keyboard is quite fragile. The best way to go about doing it, is to get a paperclip and put it under the top-left corner of the key. Be gentle! It will click, now slide down the left-hand side of the key and try popping the lower left corner of the key. Trying to rotate the key clockwise off (keep it flat down, but spin it around carefully) also helps. I realise now that I'm a left-hander, so keeping the Macbook upside down if you right-handed will help. The clips that hold the keycap in its place are on the left side of the key.
If the keycap won't give, don't force it. Take your time and take a deep breath every now and then.
You will find that in most cases, the keycap will come off cleanly. In some cases however, you might accidently rip off the inner tiny plastic layer mechanism-thingy as well. Do not despair. Hold the keycap between thumb and forefinger, and use the paperclip again to gently pry the piece out of the keycap. Now reinsert the inner piece again into the keyboard, and be sure to do it right (upside down won't work OK). Put the right side in first and shove it under the metal clip. Now use your fingers to put the tiny "hinges" into place. If your fingers are too big for this, try fiddling with the paperclip and/or a tiny screwdriver (the kind you use for your glasses).
Now reinsert the keycaps by gently pushing them into place. Make sure you get the layout right the first time! You don't want have to do the operation again.
On my Macbook, the tilde and the backslash are in a different place than expected, but this is because I have a Dutch keyboard. Click the image for a larger version.
All in all, I'm very happy with this layout, at least now I know where to find the letters!

Learning Dvorak
Dvorak can be learned in a couple of weeks if you practice a lot, but do not expect to type up to speed after only a few weeks. In my experience, it is like your brain remembers all the movements your fingers make for every word by itself. Especially in the beginning, your brain will know where to find the words and you will automatically mistype it. What I'm trying to point out is, studying the layout of the keyboard won't help you; the brain seems to remember words and not characters. For a long time, I had trouble typing words that I had not yet used after switching to dvorak. As a consequence, it is hard getting your original typing speed back.
Count on as many as six months to get up a reasonably fast speed, and don't be surprised if you're still not any faster than you used to be (often due to still making too many typo's to be blazing fast). This is one of the main reasons why critics say that dvorak isn't any better at all. I say they should give it a try; you will find that when typing text, you are using one hand more than the other using a qwerty layout. With dvorak, your hands are often alternating in a surprisingly evenly balanced manner. This is due to the fact that in natural language, words that are made up from series of alternating characters, and the dvorak layout uses this fact to its advantage. A slight disadvantage is that a programming language is not much like a natural language. If you are fluent in C, for example, it takes some getting accustomed to programming in C on a dvorak keyboard as well.

More on rearranging keyboards
Aside from the occasional application that doesn't use the operating system's keyboard layout (it is insane that this is even possible, see list below for my experiences with broken apps), you should also be mindful of what hardware you buy — unless you can type dvorak blindly on a qwerty keyboard (this is hard to learn). A lot of very standard qwerty keyboards cannot be easily converted to dvorak. Be sure to check the F and J keys, there are a lot of keyboards around that (for an unknown reason) have a different kind of socket underneath the F and J keys, and hence they cannot be rearranged.
The keys of the cool Microsoft Natural keyboard can not be rearranged.
Do not bother with keyboard overlays or writing the letters on the keys using a marker, the outcome is usually unsatisfying.
If you are totally hooked, consider getting an expensive special keyboard.

List of applications known not to work by my own personal experience:
  • A lot of games, e.g. DOOM 3 in Windows (although you can remap your keys again)
  • VNC in Linux (you can switch keymap but it seems to confuse the system even more)
  • Dell Remote Access Controller DRAC5 (odd, it did work in DRAC4)
  • Mac boot from CDROM by pressing Cmd-C (the OS hasn't been loaded yet, so...)

Saturday, February 16, 2008

A word on portability

When I first switched to Linux (it was 1993 or 1994 so, and the music was way better back then), I wrote a vi-like editor program for MS-DOS. With the help of a bunch of ifdefs, the thing would also compile and run under Linux. Some argued that this was pretty useless, because Linux already came with editors that were much more powerful than my poor clone. But the main reason I was so thrilled with it, was because the same code worked for both platforms (1). It was portable.

Linguists might say "of course", because the C programming language is portable. In practice, there are many tiny differences to be taken into account when programming cross-platform. On top of that, the differences between MS-DOS and Linux are huge (you can't argue with that).

The UNIX operating system is a wonderful piece of machinery and it runs on all kinds of hardware. All variants of the UNIX operating system look more or less the same, at least from a distance. When you start programming under UNIX you will learn the true meaning of the term "portability" (2).

Portability does not mean that your code will build on run everywhere by default. You will find out that UNIX A is not the same as UNIX B, and your Linux code may not run on BSD, AIX, Solaris, or whatever. It's the little differences that will make a big difference. Your code may misbehave, dump core, or not build at all.
To counter these problems there is POSIX compliancy for operating systems. POSIX is a set of rules that dictates what system calls are available in the operating system, and how they behave. POSIX is what makes cross-platform development possible today, although it is by no means a perfect world yet.

A great tool aiding portability is autoconf. You should clearly understand though, that autoconf is not a magic tool that makes your code portable; it is a tool that can help you rephrase your code so that it works cross-platform. As with many tools, you still have to do the majority of the work yourself (3).
Autoconf takes some time to learn, but it is worth the investment, if your project is large/important enough. It took me a week or two to make a good configure.in for my bbs100 project, but afterwards it built and ran correctly on every machine I could get my hands on -- that includes PC, Sun, IBM, SGI, and CRAY hardware. With little more effort, it was also ported to Apple Mac OS X.

Autoconf revolves around checking whether a function is available, and if it is, it #defines a HAVE_FUNCTION for you that you can use. A good configure.in script makes very specific checks on functionality that you actually need for your program to work. A lot of software packages come with some kind of default configure script that checks everything, which is totally useless if the code doesn't make use of it.

In general, a check for ifdef HAVE_FUNCTION is much better than operating system-specific checks like ifdef __linux__, or ifdef __IRIX__.
An ifdef BIG_ENDIAN works much better than checking every existing architecture with ifdef __ppc__, ifdef __mips__, etcetera. I happen to know a Linux code that completely broke because of this. Linux is probably the most ported operating system there is, but lots of people seem to believe it is a PC-only, RedHat-only thing (4).

Actually, the best-practice trick is to stay away from using autoconf's ifdefs as much as possible, and to stick with what works everywhere. Once you learn what works and what is funky, you are often able to get away with not having to use autoconf at all. A well-written program is not kept together with the duct tape that ifdef is. This is somewhat of a bold statement, especially since so many software packages run configure before build. But a truly valid question is, do they depend on autoconf that badly and is autoconf's functionality actually being used? It is a joy to see (some of) my Linux software build everywhere with a simple make.

The funny thing is, it is still hard to write truly portable code today. Last week I wrote some 2D SDL/OpenGL code on my Linux machine. When I moved it over to Mac OS X, I got a blank screen. I found up to three problems with the code:
  1. Apparently there is a slight difference in the SDL library when it comes to blitting bitmaps that have an alpha channel. The man page mentions that the outcome may be unexpected (when you blit a pixel surface over an empty surface with an alpha channel the outcome is zero; hence the blank screen) but then why does it work alright under Linux? I resorted to writing a TGA image loader and staying away from SDL's blitting functions.
  2. Resetting the polygon mode in conjunction with enabling/disabling texturing multiple times in one frame seems to confuse OpenGL on Mac OS. It messes up badly.
  3. After resizing the screen, OpenGL has lost its state and texture data and must be reinitialized. This is actually in the OpenGL standard and a bug on my side. But it does raise the question why this never surfaced on my Linux box. Apparently the (NVidia) video card has enough memory and does not get into an undefined state after a screen resize.


Lessons learned
: Test your code across multiple platforms, test, test, test..!



  1. I have yet to see my favorite DOS editor(s) run under Linux natively. Switching platforms usually means leaving your familiar apps and tools, and replacing them with a substitute.
  2. In fact, I have a feeling that the ifdef preprocessor was invented for the sake of portability. It has other uses, but it kinda smells of a "fix" for the problem of supporting different architectures.
  3. Having a hammer does not make you a great carpenter.
  4. Supporting all kinds of distributions is not easy either.

A brief history of time

I've been programming for a fairly long time now. I didn't start out as young as some did, though. My first program was a school assignment, a birthday calendar written in Commodore BASIC. I used the computer in class, I didn't have one at home.
It must have been something like four years until I went to college, got a computer, and started programming. I got hooked on assembly code and spent whole days and nights writing code.

... and that was the beginning of a whole lot of bits and bytes ...

That was a really long time ago. At some point you think you know everything, but then you realize the world has changed since then, and people are blogging and stuff. Having never written any 3D code before, I found a new challenge in OpenGL. Now, this is certainly not the most important thing that's happened to me, but it is where I am at now. So, this is where the story ends, for tonight.