Jun 052007

I concur with Ken Arnold that stylistic choice in languages should be stamped out at the parser/compiler level. In fact, the two programming languages I have on the drawing board, Pidgin (an educational language) and Animus (a more Lisp-ish Python), both do just that. Animus is strict for the reasons Arnold mentions, but Pidgin is strict mainly for the sake of learning simplicity. In designing Animus, the only legitimate place for style I found was in deciding how to spread a busy expression on to multiple lines. For example, consider a complex expression in prefix notation:

(foo a b (bar c d (moo) e f g) h i j k l)

This may seem pretty reasonable, but only because the names are unrealistically short. A more realistic version would be considerably uglier, so Animus allows you to split such an expression on to multiple lines (without getting into the particulars, Animus is indentation sensitive and has rules about leaving some parentheses implicit):

foo a b
bar c d (moo) e f g
,h i j k l

The problem here is that this is only one way of splitting the expression up, so programmers have many options in choosing which calls and which arguments to emphasize by choosing which should start their own line. I’m not really sure yet if this is a good or bad thing. You might argue that complex expressions should be discouraged in the first place by requiring such things to be refactored into multiple separate expressions using intermediate variables. However, this would make Python-style dictionary and list literals much less useful unless you made them special cases exempt from the normal rules. In any case, I’m open to introducing a rule that discourages abuses, but I think such a thing should wait for real code examples; in the meantime, it’s best to err on the side of flexibility in this area.

Posted by Brian Will
Jun 042007

How bits represent information and form the basis of computing.

An installment in a series of posts on basic computing concepts for beginning programmers.

As the general public has come into daily contact with computers, people have been disabused of their former notions that computers ‘think’ and ‘know’ things. Sadly, for most of us, the mystifying metaphor of human thought has not been replaced by some better conception of how computers work. While many people have begun to correctly think of computers as merely electrical and mechanical devices, not only do most people remain ignorant of how all the ‘gears’ work, they still can’t fathom how a computer could be made up of anything like gears, whether electronic ones or otherwise. And while we have been told to think of computers as ‘machines that do math’, most of us can’t fathom how math transforms into pictures, audio, video, user interfaces, games, or even just text.

To demystify the greater part of how computers work, you don’t have to learn all too much about computer hardware or electronics, for while these subjects are fantastically and fascinatingly complex in their own right, the role of computer hardware essentially comes down to performing a handful of simple tasks when instructed to do so—copy , add, subtract, and compare data, etc; most of the complications in hardware have to do with getting the hardware to do its simple job faster.

So it is the sequence of instructions—the software—fed to the hardware which explains the better part of the story, as this is what turns computers from calculating automatons into useful and seemingly intelligent devices. To explain software, the best place to start is in how bits represent information, for a piece of software is ultimately just a bunch of instructions and data expressed as bits, and manipulating bits is at heart all hardware does. So yes, sadly, every discussion of programming must begin with the subject of data, a topic as profoundly uninteresting as reading the phone book. Only severe autistic cases get into programming to manage data (no offense, serious autistic cases!) — the rest of us want to get our computers to do something, so do we really have to talk about something basically inert? Yes, quite simply because reading and writing data is exactly how computers do anything.

What is a bit?

As everyone these days knows, a bit is simply a thing that holds one of two states (represented with the symbols ‘0′ and ‘1′) and which can alternate between these two states, so any computer data is a series of bits, e.g. 00101111101011101111111100110100. The actual physical mechanism of ‘holding a bit state’ varies from one computer technology to another—memory chips use either capacitors or transistors; optical discs (CD’s and DVD’s) use microscopic grooves read and written by lasers; floppy disks and hard drives use charges on magnetically sensitive surfaces—but really, a bit is just an abstraction, not any particular tangible thing, so in fact, bits can even be found outside of computers, e.g. a flag on the side of a mailbox can be considered a bit because it holds one of two states, up or down.

The simplicity of bits is what makes them a good, universal, lowest-common-denominator representation of data. In fact, a bit is the smallest unit of information possible: you might think that something which held only one state would be the smallest unit of information, but you would be wrong because such a thing would not convey any distinctions, and without distinctions, you have no semantic content (see here).

Quantities of bits

Before discussing exactly how bits represent complex information, we should clear up some confusion around the terminology for expressing quantities of bits:

A single bit by itself can’t represent much, so we usually concern ourselves with series of multiple bits, and certain quantities of bits have names:

byte = 8 bits
nybble (or nibble) = 4 bits

The term ‘nybble’ is used quite rarely, but ‘byte’ is used perhaps even more frequently than ‘bit’.

(A byte is actually not always 8 bits: properly speaking, the size of a byte for a particular system refers to the size of ‘the smallest addressable unit of memory’ (i.e. the size of the cells into which memory is divided up; it is these cells which can be independently read and modified). The memory of some systems, especially some older ones, is divided into cells of some size other than 8 bits, but 8-bit bytes are found in almost all systems made in the last 30 years, including PC’s. There’s nothing intrinsically special about the quantity 8, except it has the virtue of being not too big and not too small while also being a power of two.)

We use Greek prefixes to indicate bits in certain quantities of powers of ten:

1 kilobit (Kb) = 10^3 bits = 1,000 bits
1 megabit (Mb) = 10^6 bits = 1,000,000 bits
1 gigabit (Gb) = 10^9 bits = 1,000,000,000 bits

…well, not quite. These are the popular (read, lazy), rounded-off definitions. The stricter system used by computer scientists and programmers defines these quantities in powers of two:

1 kilobit (Kb) = 2^10 bits = 1,024 bits
1 megabit (Mb) = 2^20 bits = 1,048,576 bits
1 gigabit (Gb) = 2^30 bits = 1,073,741,824 bits

(Actually, programmers very often use the lazy definitions in informal contexts—just don’t think a computer won’t notice the difference.)

The Greek prefixes can be used to indicate quantities of bytes as well, such as saying ‘one kilobyte’ to mean 1,000 (or 1,024) bytes.

Pay particular attention to abbreviations for whether the ‘b’ is capitalized or not: lowercase ‘b’, means ‘bit’, but uppercase ‘B’ means ‘byte’ e.g. ‘1 Kb’ is 1,024 bits, but ‘1 KB’ is 1,024 bytes. If you’re not paying attention, you could misinterpret a quantity of bits by a factor of eight! (You’ll also see the ‘k’, ‘m’, and ‘g’ in lower case, but this doesn’t have any significance.)

For some obscure reason, when talking about quantities of stored data, the convention is to use bytes, kilobytes, megabytes, and gigabytes, but when talking about data throughput (such as in the context of data transfer rates over a network or between computer components), the convention is to use bits, kilobits, megabits, and gigabits.

Character sets

So how do bits represent information humans care about? Well in the case of text, the relation between a particular string of bits and a text character is arbitrary, e.g. we could decide that the bit string 10111000 should designate the Roman character capital ‘J’, and as long as all of our hardware and software in the correct contexts treated that bit string as if it represented ‘J’, then it doesn’t matter that there’s no logical reason for doing so.

So to represent text as bits, we designate a unique string of bits for every character we wish to use, and this set of designations is called a character set. The most widely used character set in the Western world is called ASCII (American Standard Code for Information Interchange), which contains 128 characters, each mapped to its own 7-bit string, e.g. 1001101 in ASCII represents upper case ‘M’ while 1100010 represents lower case ‘b’.

For decades, virtually all programs written for English-speakers have used ASCII, but because ASCII doesn’t contain characters needed in other cultures, other locales used alternatives, so for many years, a hodge-podge of character sets prevailed world-wide. This began to change in the 90’s with the introduction of a universal character set, called Unicode. Unicode reserves enough space for 1,114,112 different characters, which means each character is designated a 21-bit string. As old software is being replaced by new software, Unicode is gradually being adopted as the replacement for all other character sets, including ASCII.

1,114,112 is more characters than is needed to contain all the characters of every language in the world (including even Chinese, Japanese, and Korean), and in fact, only a few hundred thousand characters are currently designated in Unicode, leaving many 21-bit strings available for future addition of characters. Some of the characters in Unicode are not language characters at all but rather symbols used for other purposes, such as math or musical notation.

Numbers

Some kinds of information, such as text characters, get by using arbitrary assignment of pieces of information to their representations, but other kinds of data are suited for a logical system. Numbers are best represented using a logical system for a variety of reasons, most obvious among them the fact that there is an infinite range of numbers, so it’s just impossible to give each number an arbitrarily selected bit string; using a logical set of rules for representing numbers allows us to encode as bits any number of any size in a consistent and predictable way.

So what is this logical system for representing numbers? Quite simply, a string of bits—11001, for instance—is a number, but in binary form rather than the decimal form with which you’re familiar: binary is nothing but a numbering system (i.e. way of expressing quantity) that works just as well as decimal. Unfortunately, while people use decimal all their lives, it becomes so ingrained that they can’t see how it works and therefore have a hard time imagining any alternative. Though the details of how binary works are really very simple once you understand them, the concept of an alternative number system is famously hard to convey succinctly and successfully to those uninitiated, so it’s something we’ll gloss over here. For the duration, just take it on faith that there is, for instance, a logical reason why 35 is expressed as the bit string 100011.

Once we have a logical correlation between any bit string and a number, it then makes sense to think of arbitrary assignments in terms of numbers rather than bit strings, e.g. if, in a character set, ‘G’ is assigned to the bit string 1000111, then it can also be said to be assigned to the decimal number which corresponds to that bit string, 71, and this is in fact how we normally think of such arbitrary assignments.

The perfect ambiguity of bits

Whatever manner is used to encode our information as bits, whether logical or arbitrary, it’s important to understand that the meaning of any string of bits is not intrinsic to the bits themselves: the meaning of any string of bits ultimately relies upon agreement between the writer of the bits and the reader as to how to interpret the bits. This is really no different from human languages, where the words of a language only have meaning because of (mostly informal) established agreements between a community of speakers of that language. It bears illustration, though, because this is not how most people commonly think of meaning. Consider:

Imagine I write 7 decimal digits on a piece of paper. Is it a phone number, the population of Milwaukee, or the number of angels on the head of a pin? Now imagine a bank that uses 14-digit account numbers. If I write down a series of 28 digits with no spaces or separators, how many phone numbers and how many bank account numbers do I have? Well, I may have known what I meant at the time I wrote those numbers down, but nothing in the data tells anyone—including myself ten minutes from then—what the numbers mean at all.

This same problem exists in computers. Consider a sequence of bits: 001110100111111110100100. The first thing not discernible is how the bits should be grouped: is this meant to be interpreted as three bytes, or six nibbles, or 5 bits followed by 19 bits, or what? Just as bad, the bits themselves indicate nothing of what kind of data they’re supposed to represent, whether numbers or text or otherwise, nor how that kind of data is encoded.

The lesson here is that, for data to be interpreted correctly, the thing doing the interpreting has to assume the length, encoding, and location of the data, and the only way to make these assumptions correctly is to strictly keep track of where data is placed and what it was supposed to mean when you placed it there.

What ensures then that, say, a file of ASCII text is interpreted as ASCII text and not treated as a bunch of numbers or perhaps as text of a different character set? Nothing! In fact, you can do the reverse: take any file and open it in a text editor to see it as ASCII text; if the file wasn’t intended to be human-readable ASCII text, you’ll almost certainly just see a sea of garbage like:

ïT¬?ì?Rïûê” ïBHïT$4ïz,ì?+ïH?;-t¦@¶ ïL$4ïQ,ï ël$?¤î? ï?ï£$+ + à +~@ï°ìV ?+Bn+K$+B?+K,¦ -+?+ LAâ-\;-|+ïåä? ¦? ;-ëL$?¤îH? ì« ? ël$$ïU ïD

…at least, it would be remarkably surprising if you opened a random file not intended to contain text but found that it happened to contain long sections of English, or any other human language, for that matter (well, actually, many files not intended to be read as text have text data embedded within them, so you will often see some strings of human language in such files). So be clear that, while nothing stops you from reading a piece of binary data as representing some kind of data which it wasn’t intended to be, barring remarkable coincidence, doing so just produces garbage.

Pretty pictures

A very large majority of all programming deals only with number and text data, but bits are also used to represent sexier kinds of data, namely images, video, and audio. At this point, how bits could possibly represent such information may still seem mysterious, so we should at least breach the matter by briefly illustrating how to represent images.

Quite simply, a computer image is just like the big scoreboard-grids of lights at sports arenas except that the individual emitters of light are much smaller than light bulbs, producing a much finer image. A computer-screen image is essentially a grid of discrete light-emitting points, called pixels, so to produce a certain image, we have to get each pixel to emit the right color.

(Of course, monitors don’t contain any light bulbs, but the physical process isn’t important to us, and besides, the actual physical process is very different between CRT monitors—Cathode-Ray Tubes, the bulky monitors that are a foot or more deep in dimension but which are now going out of use—and LCD’s—Liquid-Crystal Displays, the monitors less than an inch deep in dimension that are used in all laptops and have nearly taken over all new monitor sales for desktops.)

The solution, like with characters, is to use an arbitrary assignment: imagine that we establish a mapping of numbers to colors, and imagine that knowledge of this mapping is hardwired into our monitor; if I then feed a number to the monitor, it could set a pixel to the corresponding color. But which pixel does it set? Well, the ‘next’ pixel: a monitor is hard-wired to set the colors of its pixels in a certain order, drawing lines pixel-by-pixel, left-to-right starting from the top of the screen, moving down line-by-line, and cycling back up to the top to repeat the process. So data is fed into a monitor sequentially, thereby drawing the image sequentially, pixel-by-pixel; it’s just done so fast you don’t see the process.

The monitor image is updated from the computer at a fixed rate, usually sixty times a second or more, whether or not the image changes at all. Now, it would be horribly wasteful to have the CPU do this job itself of constantly feeding the monitor data just to show a still screen, so this responsibility is offloaded onto a specially purposed device, the video controller. An essential component of the video controller is its dedicated memory, called the framebuffer, wherein the current image to display is stored, and many times a second, the video controller transmits the contents of its framebuffer to the monitor; left to itself, the video controller can handle feeding the current image data in the framebuffer to the screen all by itself without attention from the CPU. In fact, from a programmer’s perspective, the data in the framebuffer is the image on the screen, and therefore, to change the image on the screen, the programmer simply instructs the CPU to modify the data in the framebuffer, causing a different image to be seen the next time the video controller sends the monitor the contents of the framebuffer.

The details of binary number representation and the ASCII and Unicode character sets will be presented in later posts.

Posted by Brian Will
May 262007

Why natural language in programming languages is a fool’s game.

  1. The main purpose of a formal language is that it is free of the ambiguities found in natural human languages.
  2. While naturalistic language may give off signals of familiarity and thereby boost a programming language’s approachability, the gain is more than offset by the increased complexity which naturalism introduces, complexity which learners will very quickly be confronted with. Naturalism acts as a mask for language complexity, not a substitute for it.
  3. I for one am skeptical of the ‘cult of smartness’ found in programming culture, but even I will say that a learner new to programming just isn’t going to cut it if they can’t adapt to the concept of a formal language: if you’re hanging on to those bits of typical programming languages that happen to be English-like (e.g. control words like ‘if-else’), then you just aren’t getting it.
  4. The usual bits of English-like syntax found in our languages are often more misleading than helpful.

This last point can be illustrated with the keyword ‘while’. The keyword ‘while’ obviously was introduced with a sentence in mind like, ‘Do this stuff while this condition remains true.’ Problem is, this sentence, as understood by the typical English speaker who is not already versed in a C-like language, would not convey what ‘while’ actually does; the sentence only sounds good enough as a description of ‘while’ to programmers already familiar with the ‘while’ construct.

A more accurate sentence for describing ‘while’ would be, ‘If this condition is true, do this stuff, otherwise move on; after every time you do the stuff, test the condition again, doing the stuff if true or moving on, ad infinitum.’ Notice the absence of the word ‘while’. Also notice that the sentence which the originators of ‘while’ did have in mind is not what a newbie to the language is going to see—they will just see the word ‘while’.

Not only is ‘while’ not really evocative of its function, it easily misleads: a very common misconception learners get is that a ‘while’ loop will end the moment the condition is made untrue inside the loop rather than when the block completes and the condition tested again; many learners likely get this misconception because it is consistent with the sentence, ‘Do this stuff while this condition remains true.’ Learners would be better served were ‘while’ instead arbitrarily named ‘friedchicken’ (perhaps ‘kfc’ to save on typing).

Now, of course, not all English-like elements are so poorly chosen—’if’ is pretty sensibly named, though I would have gone with ‘otherwise’ in place of ‘else’—but the acceptable cases are few enough that one can hardly say there is much benefit in attempting to conform to an ideal of naturalism. You’ll likely just do more harm than good.

Posted by Brian Will
May 212007

This last week I’ve been getting familiar with Vim. I’ve dabbled a few times in the past, but this time I’m finally feeling comfortable enough to stick with it. I was quite annoyed with having to hit ESC all the time, but a neat tip is to set this in your config file:

imap jkl <esc>
imap jlk <esc>
imap kjl <esc>
imap klj <esc>
imap ljk <esc>
imap lkj <esc>
set timeoutlen=500   " cuts down the pause time you'll see after typing j, k, and l

…so now you can get out of insert mode by smashing ‘j’, ‘k’, and ‘l’ simultaneously. This will, of course, conflict if you ever need to type one of these sequences, but those are surely quite rare and work-around-able. I’m even going to experiment with reducing this just to ‘j’ and ‘k’, which is itself a really rare sequence in English. (Maybe ’s’, ‘d’, and ‘f’ or just ‘d’ and ‘f’ can be set to ESC as well.)

If you don’t like that solution, other good choices are:

imap <S-space> <esc> " shift-space to get out of insert mode

…and:

imap <S-enter> <esc>  " shift-enter to get out of insert mode

I mention Vim because I recently played with the alpha of Archy, which is a project to implement the ideas of the late interface theorist Jeff Raskin, and its text editing mode feels much like Vi stripped down to the essentials for the common user. Here’s a quick summary of Archy’s interface:

  • The primary part of the interface is one big text-editing window; there’s only one sequence of text, but the text is separated into ‘documents’ by special divider lines (which are inserted by the ` key).
  • Navigation up and down the big glob of text is done primarily by holding down an alt key and typing a string of text to “leap” to. Using left-alt does a back search for that string while right-alt does a forward search. Releasing alt takes you back to typing mode at the location you just leapt to. To repeat your last search, hold capslock and tap alt (right-alt for forward searches, left-alt for back searches). Having to hold down alt while typing is pretty awkward and uncomfortable after a while.
  • This ‘leaping’ feature with the alt-key searching is also how you select text: the selected text portion is always the section between the place you last leapt from and leapt to.
  • The user issues commands by holding down the capslock key, then typing the command. E.g. [capslock]-C-O-P-Y to copy the highlighted text. Even with auto-completion, having to hold down capslock while typing is pretty awkward, especially if the command contains an ‘a’, ‘q’, or ‘z’.
  • Text can be formated (coloring, fonts, style, size, alignment, etc.) by highlighting text and issuing a command.
  • And for some reason, to get a key to autorepeat, you must triple-tap it before holding it down. (This is really annoying, especially with the navigation and backspace keys.)

Text-editing is the only part of the alpha, but Archy’s other key component will be what they call the Zooming User Interface (ZUI), which I take it is where non-textual elements will reside. How these components will fit together, I’m really not sure.

What to make of this? First, I’ll say there are some things I admire about this approach—mainly, Archy bravely recognizes average users can cope with a few non-discoverable elements: as long as the set of basic concepts to learn is small and worth the pay off, it’s OK—contra Steve Jobs—to expect users to learn something. Archy strikes me as an attempt to bring the Unix philosophy to the masses: rather than relying upon packaged solutions to problems, users are encouraged to build upon a base of simple yet powerful mechanisms; Archy simply starts from a clean slate, dispensing with the accumulated detritus of 40 years of terminals and programmer conventions, keeping things tidy, sacrificing power for approachability.

This said, there are glaring faults with Archy as currently available. First, having users hold down alt and capslock while typing is clearly not going to fly, as it’s difficult for even expert users, let alone the majority of users that have trouble touch typing. Yes, the purpose is to eliminate modality, but this is clearly not a realistic solution. (Maybe we need special keys below our space bar which we can hold while typing more naturally, or maybe the spacebar itself could be used.)

Really, modality is not as bad as UI orthodoxy claims. Keep the number of modes few and try to eliminate unnecessary ones, surely, but modality is extremely powerful, and to do it right, you really just have to give unmistakable visual, auditory, and feedback cues to the user conveying what state the interface is in. (A good test is to see what happens when users step away from the computer then come back later; if they mistake the mode they’re in, you have a problem.) Archy’s cues are just too damn subtle. For instance, I found myself confused when I started typing because sometimes Archy would move my cursor to some other document; turns out I was trying to type in a ‘locked’ document, but it took me a number of tries to figure this out as the message Archy briefly flashes is black text superimposed over very similar black text at the top of the screen; it’s great they didn’t annoy me with an ‘OK’ pop-up, but there’s unobtrusive and then there’s covert. In general, Archy has far too few elements of on-screen guidance, likely because the developers are too enamored of the idea of an interface-less interface. At the very least, Archy should have a training mode in which at least some screen real-estate is devoted to guiding new users.

Also problematic is how Archy messes with the user’s expectations about character keys, giving the keys surprising behavior in certain contexts such that they don’t always produce their usual characters. Now, there are obvious cases where average users quickly adapt to character keys not producing their respective characters on screen—games, for instance, often make use of the alphanumeric keys for non-text purposes—but such programs usually clearly delineate between typing mode and non-typing modes. In contrast, Vi, Emacs, and now Archy violate this barrier, messing with character keys in the context of typing text. In Archy, you find yourself in a few annoying moments like you do when first using Vi(m) where it’s not responding like you expect and you just can’t understand why.

Fortunately for Archy, both of these faults—inadequate cues and poor key assignments—can be fixed, but I wonder if the project will be willing to do so, as it requires compromising on its ideals of a totally modality-less and interface-less interface.

Posted by Brian Will
May 202007

A while ago, I proposed a website for funneling donations from ‘content consumers’ to ‘content producers’, and it turns out others have a similar idea and are doing something about it but framing the idea as ‘tipping’ rather than ‘donating’. Nick Szabo, who wrote the best early assessment of why micropayments won’t work back in 1996, comments on this, suggesting that the social aspects of real-world tipping should be embraced in their online form:

I’d add generosity signal features that inform one’s friends or fellow tippers as well as the tipee about the tip. This could be in the form of aggregator “karma” points that name and ranks the most generous tippers. This would be like the “karma” points which people who add content to a social aggregator compete for, but it signals far more — it signals that one is a generous tipper as well as a generous contributor of recommendations. There are a variety of other ways (home or facebook pages, e-mail, etc.) that generosity signals might similarly be sent within a social circle.

My gut objections to this are that:

  1. It’s tacky to make a public show of one’s generosity.
  2. I’m already increasingly overwhelmed by noise drowning out my incoming and outgoing signals. Information on the tipping habits of others strikes me as just more minutia competing for my attention and distracting others from paying attention to me.
  3. We don’t need more markets for buying attention and prestige. Plenty of those already.

I’m not so concerned if we’re talking about keeping information about each user’s personal tipping behavior strictly within that user’s personal group of people they choose to associate with, not the random mass of people who happen to also use the service. That is obviously useful and just a natural extension of what happens offline.

I am concerned, though, about emphasizing the aggregate behavior of the whole user base, such as is done with mass-actor networks like Digg and Reddit; though I use those sites, I dislike how the form—a single feed, basically—turns the affair into a competition between factions for control. If designed poorly, the social mechanisms of a donation/tipping network could result in the same distortion and gaming effects.

Unlike Wikipedia, where the goal is to discourage factionalism, a donation/tipping network is best served by simply allowing different factions to go their separate ways. I don’t really see this as a loss: you just aren’t going to find much ground of agreement between crunk enthusiasts and Parrotheads.

Posted by Brian Will
May 042007

From the creator of JSLint, Douglas Crockford, here’s a series of Javascript video lectures. It just so happens I’ve been spending the last four months working in Javascript for the first time, and I wish I’d seen these lectures before I started.

The first thing Crockford tells you is that all the Javascript books out there—with the partial exception of the O’Reilly rhino book—are crap, and I’ll corroborate that. Crockford will save you a great amount of time by cutting directly to all the features, quirks, virtues, flaws, and subtleties of Javascript that make it unique, while giving you invaluable advice on best practices. Also check out his videos on the DOM.

The only issue I take with Crockford is his estimation of the language. He’s certainly correct that Javascript is far under-appreciated by ‘real programmer’ snobs and that Javascript’s biggest weaknesses lie in the browser development environment, not really in the language itself. But I’m not convinced, for instance, that prototype inheritance is really the way to go; it’s perfectly possible to have modifiable-at-runtime inheritance with plain-old-classes, and in fact Ruby and Python offer just that. Nor do I think Javascript should get too much credit for many things it does right: for just about everything Javascript gets right—with the notable exception of function literals—Python gets more right, and did so before Javascript did. Moreover, Python fixes many things that are just plain wrong with Javascript, such as Javascript’s lack of a proper file-linking mechanism.

On the other hand, Python’s built-in namespace has the same problem as Javascript’s global namespace: a mis-typed identifier can’t be flagged as an error by the parser because the parser can’t know if that name exists in the global namespace or not. Sure, getting rid of the global namespace wouldn’t catch mistyping ‘bar’ in ‘foo.bar’, but it would catch a significant number of such errors, and nothing really would be lost. (I don’t consider modifying the built-in namespace to be a legitimate Python practice, and I’ve always found Python’s meta-language features—the modifiable built-in namespace and operator overloading—to be invitations to bothersome errors and quixotically at cross-purposes with Python’s philosophy of imposing stylistic uniformity.)

Posted by Brian Will
May 042007

Title translation: ‘Don’t tell me you find this difficult to understand purple monkey dishwasher (version 3)’.

Preston Gralla on O’Reilly Net complains that Linux package names are preventing wider Linux desktop adoption. While I find his claim that Linux will never get there extreme, I do agree this is a significant hindrance.

Such package names simply shouldn’t be presented to regular users at all, even in the context of browsing packages. Sure, people can just ignore them, but don’t underestimate the psychological toll of being confronted with a stream of information you can’t even categorize let alone understand.

More generally, I oppose the Unix/old-style-programming practice of privileging ease-of-typing and compactness in names over descriptiveness. Even for those attempting to verse themselves in the lingo, the level of contextual familiarity presumed by this preponderance of abbreviations makes the learning curve very steep.

Posted by Brian Will
Mar 272007

Dmiessler makes a good point I’d been meaning to make myself: the axiom against ’security through obscurity’ is often taken too far. First of all, any kind of cryptography, whether the algorithms are publicly known or not, always ultimately relies upon ‘obscurity’ in the form of an unrevealed piece of information, the key. Second, well, just ask Osama bin Laden.

Arguably this comes down to a semantic disagreement: ‘obscure’, here, surely means ‘unrevealed information’, but the authors of the phrase ’security though obscurtiy’ also seem to assume ‘obscure’ implies ‘reliance upon unrevealed information that is guessable by brute force means (no matter how arduous, as long as it’s doable) or derivable by logic (no matter how byzantine)’. I don’t think everyone shares that definition, hence a lot of unnecessary back-and-forth around this slogan. (Not that there isn’t a real substantive disagreement here—just that much of the argument is probably unnecessary.)

Posted by Brian Will
Mar 262007

I don’t have to be Aunt Tillie to crave a simpler desktop computing experience. Whether I’m using Windows, OS X, GNOME, or KDE, my current work flow gets tangled as I juggle several open folder windows, half a dozen instances of Firefox with 30 tabs between them, a text editor, Google Talk, Eclipse, terminal windows, a media player, and sometimes more; on top of this is the ever expanding mess that is my hard drive. This basically sums up my two main computing problems: my desktop is an unstructured mess of windows, and my hard drive is (between major cleaning jaunts) a mess of files.

The second problem, the files problem, is being partially addressed by desktop search (Google Desktop, Beagle, etc.), but that solution doesn’t really help keep my drives clean—it just let’s me cope better with the mess I create. I think the real solution will be in adding tag-based directory structure onto our current hierarchical directory structure (yes, we would have to meld the two), but that notion will have to wait for a later post.

As I argued in the previous post, the root of the first problem (window management) lies in the desktop metaphor itself and the dominant GUI conventions of the last twenty years. To deal with this problem, we should first step back and analyze what purpose the desktop serves. The GUI desktop is, at a minimum:

  • An interface for starting applications, for switching between open applications, and for allotting screen space between open applications.
  • A common set of interface elements for applications, often including guidelines for the use thereof to achieve a cross-application standard look-and-feel.
  • A data sharing mechanism between apps (copy and paste).
  • A common mechanism for application associations—what applications should be used to open such-and-such a file or send a new email, etc.
  • A set of system-wide keys, e.g. ctrl-alt-delete on Windows.

And because most users don’t/can’t/won’t use a command-line, desktops include a minimum set of apps:

  • File management.
  • System/hardware configuration and system utilities (e.g., a GUI non-destructive partition resizer—which has been too long in coming to Linux live-CD’s, frankly).
  • Program installation/removal.

So what should the desktop not do? The standard Linux distros all come with an additional assortment of basic apps (web browser, office suite, mail, etc.), which is great, but I think integrating such things into the desktop (or giving naive users the illusion of integration) is very risky and of dubious benefit. The problem with such notions is that they smell of ‘ad hoc-ist design’, i.e. design which tries to meet needs by making exceptions to the rules rather than by applying the rules. Ad hoc-ist design evinces an unfortunate fact about design: it’s easy to come up with features; the hard part is devising features which make other features unnecessary. At a minimum, ad hoc-ism fails to minimize complexity; at it’s worst, ad hoc-ism introduces complexity, and that goes for all parties— for designers, for implementers, and for users. If your design evinces ad hoc-ism, it’s likely because your core mechanisms don’t fit your needs well enough, so rather than piling on more features, it may be time to rethink those mechanisms. Any proposal to expand the desktop should heed this advice, but most such proposals I’ve seen don’t (e.g. see here).

For instance, writing two years ago on O’Reilly Net, Jono Bacon (of LugRadio fame) suggested that project management should be promoted to first-class status as part of the desktop [link]. Jono’s suggestion basically requires three things: 1) integrating features of a personal information management (he calls it ‘project’ management) application into the desktop; 2) implementing an automated personal information data sharing mechanism for applications; 3) making applications work with this mechanism.

Now, Jono may actually be on to something here: his core complaint is that some applications should be able to automatically share certain kinds of data. Problem is that automated data sharing between desktop apps in general is the proper problem to tackle—after all, what’s so special about PIM? Now, lack of a general desktop data-sharing mechanism—let alone an automated one—is actually a long standing problem. Arguably the time for a solution has come, but narrowing the problem and tying the solution to programs of a specific domain would be hurtful in the long run, both for the sake of solving the general problem and the domain-specific problem: the mechanism that would result would likely be too tightly coupled to particular apps, discouraging the formation of an ecosystem of competing experimentation and natural selection.

I can understand Jono’s frustration: the Unix people tend to see every data sharing problem in terms of the mechanisms already existing in Unix (there are quite a few of them, after all), and so they don’t exactly rush to fill in gaps that hinder certain problem domains. Who knows, maybe something already exists to meet desktop data sharing: copy and paste via web services, anyone?

Anyway, I’ll finally present my desktop UI design later this week.

Posted by Brian Will
Mar 192007

Continuing a discussion of desktop UI from the previous post. Be clear that most of what follows applies equally to Windows and the Linux desktops; my point is that Apple popularized these ideas and the others—-misguidedly—-still follow Apple’s lead.

Compared to Microsoft, I don’t especially begrudge Macs for their existence, and I do recommend them over Windows to naive users who don’t have anyone to maintain and set up their boxes for them. Still, it annoys me how many people have drunk the Apple koolaid and believe that OS X has anything on the basic Windows experience beyond gloss (and an ‘it just works’ quality earned only by a controlled, minute hardware and software landscape); just about everything beyond a few features of the OS X interface is just arbitrarily different from other desktops. Macs wouldn’t annoy me so except for how their influence perpetuates through fashion stupid graphical interface design ideas which both Microsoft and Unix desktops have slavishly followed. Contrary to popular opinion, Macs are not the end-all/be-all of usability, and in fact, Macs have long perpetuated some erroneous thinking about usability. There are several things seriously wrong with the desktop/windows metaphor, and Apple is responsible for most of them.

Continue reading »

Posted by Brian Will