February 2003

« January 2003 | Main Index | Archives | March 2003 »

28
Feb

Okay. While I still can't sleep, a quick straw poll. Whoever wrote the Java interface to Applescript for OS X was:

  1. So comfortable with AppleEvents that he or she just wanted to replicate them verbatim in a new syntax, instead of providing a useful abstraction
  2. Completely ignorant of the Java Language
  3. A sadist
  4. All of the above

If you answered 'd', you're most likely correct!1 I spent a very frustrating Sunday afternoon putting together what should have been a simple servlet that puts my current iTunes song in the side-bar of the front page of this site. 75% of that time was spent with me being frustrated trying to decipher the totally opaque NSAppleEventDescriptor object that the AppleScript call returns. The whole class is so encrusted with legacy cruft and assumed foreknowledge, it's almost impossible to work with.

1If you answered '4', your browser's list-style-type support sucks

Ouch.

  • 4:13 AM

It's 5am. I was woken up about an hour ago by my own head. It feels like it's over-full, like somebody needs to drill a hole in my skull to let the pressure leak out. It's really quite painful. I can't get back to sleep, because even after two Neurofen, my usually quite comfortable pillow feels like it's made of concrete.

This sucks. I hate being sick. If it's something stupid and my own fault, like a hangover, or the time I tried to leap over that rope at work and gave myself concussion, I tend to just grit my teeth and get through it, but at times like these when it's just my body letting me down against invading microbes, or whatever-the-hell environmental toxins or internal failings that cause headaches, I tend to get whiny and pissed off with myself for not functioning correctly.

Sure, I could treat my body better. It could do with more exercise, and a better diet. (or maybe this is my body reacting violently to the fact that I actually fed it a large quantity of salad yesterday, and it was unused to the nutritious content?) But still, it's let me down this morning, and I'm not going to forgive it easily.

Ouch. Still hurts. Must get email off to work telling them I'll be late, and go back to that concrete block.

YKYBHTLW...

  • 7:15 AM

You know you've been hacking too long when...

You see the band-name ZWAN (link warning: obnoxious colour-scheme and dancing spam), and your first thought is “What does the Z stand for?”

The last interview I did was over the phone, for a job halfway across the country. Now that was stressful. Doing a phone interview makes you realise just how important body-language is, especially that attitude in an interviewer that says ‘OK, you've talked enough now, finish what you were saying so I can ask another question.’ Over the phone, in the absence of such clues, the interview tends towards you talking until you've bored the interviewer to tears, or tailing off into embarrassing silences where both sides try to work out which is due to talk now.

Anyway, I was reading artima.com's article How to Interview a Programmer, and the following leaped out at me. Joshua Bloch and Bruce Eckel had both just suggested getting an interviewee to perform some kind of design or code snippet, which garnered the following responses:

Scott Meyers: I hate anything that asks me to design on the spot. That's asking to demonstrate a skill rarely required on the job in a high-stress environment, where it is difficult for a candidate to accurately prove their abilities. I think it's fundamentally an unfair thing to request of a candidate.

Matt Gerrans: I don't like when I'm asked to write a program that does X on a piece of paper. Don't ask the candidate to write a program on paper. That is a waste of time and sweat. People don't write software on paper, they do it with computers using auto-completion, macros, indexed API documentation, and context-sensitive help. They think about it, refactor it, and even rewrite it. If you want to see a person's work, ask them to write some small module or implement some interface before the interview and bring the code on a notebook PC or on hard copy. Then you can review it and discuss the design, coding style, and decisions that went into it. This will give you a much more realistic and useful assessment of a person's work and style.

import com.aol.*1

I'm not a bad actor. Or at least I have the potential to be not a bad actor. But the thing that kept me out of acting in university (well, aside from the fact my older brother was President of the dramatic society, and I didn't want to be seen as following him) was that I'm very bad at improv. In all the auditions I attended, one of the things that was asked of you involved improvisation, and when you put me on the spot like that, I dry up. I'm creative, but if you point at me and say “Create something! Now!”, chances are I'll not do it very well.

I'm a good programmer, and a pretty good designer. On all other counts, I'm told I interview quite well. That said, if you put me on the spot and say “write this code in the next five minutes”, I'll flounder around, and probably make a pig's breakfast of the whole thing. Burningbird recently had a similar problem: knowledge that would normally come effortlessly abandoned her during the interview.

When I'm presented with a design problem to solve, you won't find me sitting in a chair with a piece of paper. You'll find me wandering aimlessly around the office with a can of coke, or tossing my pen in the air and catching it. You'll see me doodling on a whiteboard. You'll see me wander out the front door with my iPod playing at maximum volume, and walking around the block. When I need to think creatively, I get my best ideas when my feet are moving, not when I'm sitting in front of a computer, or in a meeting being pressured to come up with an answer right now. I guess my approach quite closely resembles that of the Postmodern Programmers2

:

To write this program, we first connected our computer to the Internet, downloaded some music from Napster, and then read our email. (You have to receive email to perform a workday [11]). We received 25 pieces of email of which 16 were advertisements for Internet pornography, administriva, or invitations to invest in Nigerian currency trades. After dealing with this email, we typed ‘calculate prime numbers’ into Google. This found several web sites regarding prime numbers, and some more pornography. After a while, we were interrupted, and so moved on to the prime number web sites.

This may sound like a wasteful way to do things, but I find that the way I work is well suited to my mind, and if I'm allowed the freedom to wander around, go for my walks around the block, and generally look like I'm not working, I get things done much faster in the long-run. I'm reminded of a Dilbert cartoon I can't find a link to, where Dilbert was asked to fill in a timesheet: “So, I should fill in all the time I spend in pointless meetings, but not the time I spend in the shower thinking about circuit design?”

Maybe this leaves me with a certain bias against the “ask the programmer to solve a problem in the interview” approach. Or maybe it's just that the approach is an interviewing technique, not an interviewee technique. The interviewer is looking for someone who fulfils the requirements of the job, not for everyone who fulfils those requirements. If a few people who have the job skills, but not the interview skills, slip through the cracks, so long as somebody else shows up who is qualified, and who can jump through the interviewer's hoops, that's only really a problem for the person doing the slipping.

1 “Me too!”

2 Well, aside from the whole pornography thing. The closest I've come to viewing pr0n at work is when some inconsiderate person on my livejournal friends list has replaced their userpic with something obscene.

[11] throw new DanglingFootnoteException(11);

It's been pointed out to me once or twice that I don't enable comments on my posts. Today, I read that this is the number one habit of highly annoying bloggers. Oh well, I'm innocent of the other nine.

My rationale is pretty simple: if someone wants to comment on a post I've made, I'd much rather they post the comment in their own blog and link it to me, rather than putting the comment in my blog. Why?

  • If I post something interesting enough to pass comment on, a link gives the original post a wider audience.
  • A comment will be read only by those people who view the article after the comment is posted.
  • If I respond to a comment in the same forum, chances are the original commenter isn't going to read it, because they'll forget to check back.

Essentially, responses in the blogosphere promote conversation, and widen the field of discussion. Responses in comments tend to bury it. That said, it seems that I'm in the minority, and being annoying. I'm going to experimentally start enabling comments for a while, just to see if anyone actually wants to comment on the drivel I produce.

As my inaugural comment-enabled post, I'd like you, dear reader, to introduce yourself! Do you read my weblog, and I don't read yours? Post a comment and tell me where I can find you. Do you read my weblog and don't have one yourself? Post a comment just to say hi. I'm curious. I get about 3,000 hits a day even on days don't post anything at all, so there must be a few of you that I have no clue about.

(Oh, and to anyone reading this syndicated on livejournal, you'll have to click-through to the original post to get at the comments page here: I don't read the ones posted to livejournal)

Organised Cows

  • 5:19 PM

Don't miss Alan's explanation of Software Development Cows.

Merge Cows
Trying to put your cow into the same part of the code somebody else already put a cow.

I'm sure some people in the office wonder why the three of us greet each other in the morning with a hearty “moo”. Or maybe they don't. Programmers tend towards eccentricity anyway.

I've been trying to write this article for at least six months, but after three or four false starts, it's never quite come out right. So now I'm going to just sit down and get the words out, and not try to be a perfectionist about it.

This all started back when I first tried Spaces. All credit to Diego, it's a very impressive application, bringing together a lot of diverse data and trying to present a unified interface to it. But after about half an hour of playing, it became clear to me that I had substantial philosophical problems with a program that wanted to be a RSS aggregator/blogging tool/mail manager/calendar/God knows what else.

Premise 1: Programmers like to generalise data.

To a programmer, Instant Messaging and E-Mail are the same thing. They're both structured messages sent from one user to another over the Internet. The mechanisms used are different, but the differences aren't that great. In fact, there are just as big differences between the various forms of IM. If you took Internet e-mail, replaced POP with a presence-based system between you and your ISP, and allowed other e-mail users to query that presence, you'd end up with an architecture that is closer to Jabber than Jabber is to AIM.

So why do none of the mainstream IM applications look like e-mail applications, or vice-versa? Because when you move up away from the level of data moving around, the uses to which people put the protocols are entirely different. IM is immediate and ephemeral, e-mail is asynchronous and long-lived. IM is off-the-cuff, e-mail is more formal and official. (Interestingly enough, a few years ago we were making exactly the same distinction between e-mail and snail-mail.)

Premise 2: Once upon a time, it was a good idea to have do-everything applications.

When graphical operating systems were young, sharing data between different applications was hard. Having the user switch between applications was hard, and often completely beyond the user's understanding. This led to the rise of monolithic applications that tried to be entire computing environments. Word Processors and Spreadsheets agglutinated together to become integrated suites. Web browsers sprouted fungus-like growths of mail- and news-readers. Mail readers grew calendars and scheduling applications.

Unix nerds scoffed, coming from a background where unless you were one of those emacs weirdos, your email program didn't even have its own text-editor.

These days, the problems aren't nearly as great. Mainstream operating systems are much better at running multiple applications, users are better at navigating them, and the underlying API for cross-application communication and embedding have matured (although ironically Unix programmer tend to lag behind, accusing things like Orbit of KParts as being bloatware: “if pipes were good enough for my father, they're good enough for me!”. The uncharitable side of me would suggest that it's easier to dismiss something than learn how to use it.)

Premise 3: Applications that try to do more than one thing suffer as a result.

The current generation of user-interface, which is yet to spawn a replacement, has a certain upper-limit of complexity within a single application. On a practical level, there are only so many things you can put in a menubar, toolbar or preferences dialog before it becomes user-hostile.

The situation is at its worst when an application does a number of unrelated things. Take a look at Mozilla, which should never have copied Communicator's outdated ‘everything in the one application’ approach. Take a look at Evolution, the Outlook-alike for the Gnome desktop. It does e-mail, calendaring and even RSS aggregation. The only way it can do so, is by introducing the one thing you should avoid at all costs in a graphical application: modes. The contents of the menu-bar change radically depending on what task you're performing. This, however, means if you're trying to find a particular function, you must first find how to activate the mode that function forms a part of.

Premise 4: Sharing data is good.

One of the things that annoyed me at first about iChat, Apple's AIM client, is that to add someone to your contact list, you have to create an entry in your system-wide address book for them. This seemed to me to be a complete waste of time. Then I discovered that because address-book data is shared by other applications, when I receive an e-mail from someone who is also online via AIM, a little green dot appears next to their name in the mail-client, and it will allow me to send a reply through iChat. This is only possible because the Address Book knows that the email and the AIM ID belong to the same person.

The value of a network grows exponentially with the number of nodes. So does the value of a network of applications. Each interaction between cooperating apps can add value to both the supplier and the consumer of information. On its own, the Address Book in OS X is pretty useless. But by being a central repository of contact information that all other applications (and devices, thanks to iSync) can leverage, it enables a raft of functionality in other applications that just wouldn't work without it.

Conclusion: Write apps that provide a specialised interface within a single domain, but that draw data from (and contribute data to) a system- or even network-wide datastore. (look at Apple's embrace of ZeroConf/Rendezvous, or Newsmonster's proposed P2P sharing of RSS headlines) Leverage the APIs that allow you to have applications co-operate, and always provide an open API to allow other applications to draw information from, and manipulate your program.

Generalise your data. Specialise your apps. Computing nirvana will follow.

From Livejournal's status page:

LiveJournal is currently under a Distributed Denial of Service attack, and has been since about 5:30pm PST (1:30 AM GMT) tonight. We have been working with our upstream providers (including several major backbones) to filter traffic as quickly and effectively as possible.

Due to the fact that a DDOS attack involves potentially tens of thousands of hosts all working together against a single target (in this case, us), it is extremely difficult to find one group of IP addresses to block to prevent the attack from affecting our services any further. Our upstream providers are currently filtering somewhere around 1/4 of the IPs on the internet from reaching LiveJournal. Unfortunately, these filters also block legitimate traffic from some users. When the attack has subsided we will remove the filters.

We will continue to monitor and block hosts as we gather more information regarding this attack. We seriously apologize for the inconvenience, and hope you understand we are doing everything in our power to get the site back functioning as normal.

Additionally, if you have any information as to who or what may be responsible for this attack, please email attack_info@livejournal.com.

Firstly, this is a really good argument against centralisation. If you have 500,000 users on one server cluster, that becomes a honking big target, and an attack on any one of them becomes an attack on them all. It used to be just IRC servers that got this sort of treatment, and occasionally the bigcompany websites. Now the precedent has been set for knocking Livejournal off the air, look for this sort of thing happening to more mid-size web services that somebody takes a dislike to.

Secondly, I bet if you were to find the person doing this, and asked them why, they'd say “Because Livejournal's lame, you know?” It still sucks that a couple of idiots with no moral sense can screw up such a popular service.

Thirdly, my sympathies to the sysadmins who have to deal with this mess.

I'll have to write an article about DDOS soon. You can tell I've been working hard recently by looking at the calendar: all the posts are clustered on weekends, and they've not been about programming, because my mind's been trying to avoid thinking about that when I don't necessarily have to.

These pictures really don't do justice to the size of the crowd that turned up in Sydney today to protest against Australia's involvement in any war in Iraq.

“A democratic society depends upon an informed and educated citizenry.” —Thomas Jefferson, quoted today by Rogers Cadenhead.

The death of democracy is inextricably linked to the transformation of the news media from journalism into entertainment.

News as journalism seeks some approximation of ‘the Truth’, to inform and educate its public. As such, it must:

  • Present a balanced viewpoint, including both sides of any issues covered.
  • Cover (and emphasise) stories based on their overall importance to the target audience.
  • Ask difficult questions of those in power, and demand answers.

Journalism as entertainment, on the other hand, has the sole aim of gathering, and keeping an audience, usually to funnel the audience to advertisers. As such, it must:

  • Present a viewpoint that does not offend the opinions of its target audience.
  • Cover (and emphasise) stories based on their immediate emotional impact on the audience.
  • Ask only those questions sanctioned by those in power, so that they continue to favour your organization with appearances and information.

Of course, things were never as pure as the first list, neither are they now as corrupt as the second. My mother told me a frightening story last week about my uncle, who was a Fleet St editor, and quit the business because between the interests of the paper's conservative owners, and the threats of the socialist printing unions, he had very little leeway to report anything. Even given that, it's pretty clear that the world of the media has been sliding down the slope between the first and the second extremes for quite a while now.

As an aside, this is one reason weblogs aren't journalism. Weblogs present a single side of an issue (the author's), and cover stories based on the interests of the author. Since people gravitate to opinions that match their own, it is unlikely that a weblog will ever challenge your prejudices, or at least it is unlikely that you will read it again after it has. The one thing weblogs have been good at, is in asking questions that the mainstream media is no longer able to.

The downfall of political reporting is well-documented. Politicians always knew they needed the media, which gave the media power. However, one day the politicians realised that the media needed them just as much. By selectively giving exclusives and interviews, politicians can condition the media. It's Pavlovian. Don't ask the difficult questions, you get more interviews. Report favourably, and you get leaked more information. Get more interviews, scoop your competition with the new stories, and you rate better than those who have the questions, but nobody to answer them.

Which means that while it's good that weblogs can dare ask questions that the mainstream media aren't asking, they're unlikely to ever get answers to them, unless there's so much noise that the mainstream media is embarrassed into action.

It's getting to the point where opinion polls on war in Iraq contemptuously ignored by my country's government, because those in power trust the power of their media allies to convince us they're right, and we're wrong. Where we all have questions we want to ask our elected officials, but get no answers because those in the position to ask them for us have their own agenda.

The public are not informed and educated. We are pandered to, and fed information that suit the agendas of those who dispense it. Don't think I'm excusing myself here. I am a socialist. I gravitate towards media that validates my opinions just as much as any die-hard American Republican glues himself to Fox News. I just wish there were a middle route.

Moving, maybe...

  • 12:31 PM

Disadvantages of the apartment I just applied for: I hate moving, $100/wk more in rent, not as convenient for 7-11 or restaurants. No built-in wardrobes.

Advantages, on the other hand: Slightly bigger. Cable already installed. And, er...

A really great view of the Sydney Harbour Bridge.

For a long time, I've considered Javascript to lie somewhere beneath my contempt as a language. Which is a pity, because it's not really Javascript's fault. Browsers' support of the language has always been underwhelming, and grossly incompatible. in the past, whenever I've tried to do anything with Javascript it's taken far too much time, and because the capabilities just weren't there, it never never quite worked the way I wanted it to.

Javascript itself is a small language, but that wasn't the problem. The problem was that what we generally refer to as being ‘Javascript’ is really the intersection of the language itself, plus the DOM (and to some extent CSS) support of whatever browser it's being run in. And it's only in the last year or so that web browsers have had anything approaching decent DOM/CSS support.

Secondly, the annoyance factor of so many people not being able to tell Java and Javascript apart (curse you, Netscape marketing weenies!) made me prejudiced against the language whenever it was mentioned.

In the last few days, I've finally had the chance to get down with my two-inch thick O'Reilly DHTML book, and write a useful scripted page for the project I'm working on. Here's what I learned.

  • Javascript's object model is simple, very flexible, and pleasant to use.
  • I really liked having first-class functions and closures. I found myself writing things like ["id1", "id2", "id3"].map(function(item) { return document.getElementById(item); });. A cow orker looked at what I'd written and accused me of being too Smalltalky (and I've never coded Smalltalk seriously)
  • DOM support in version 6 browsers is very good. Manipulating a webpage is surprisingly easy. (Although my point of reference here is the Version 4 browser, when I last attempted this sort of thing)
  • That DHTML book is incredibly good, and no web developer should be without it.
  • This sort of thing is only really practical if you forget that browsers older than Mozilla or IE6 exist.
  • While I had the luxury of targeting my code at a single browser version, everything I did could easily be made cross-browser in half an hour (taking into account the previous definition of “cross-browser”.
  • Being a closet HTML nerd (and thus knowing where to look for things in the HTML DOM, and what CSS to manipulate to make things move around or disappear) helps.
  • Most importantly, spending two days learning a language I've never really programmed in before, in order to fulfil a valuable goal, is a good experience. I really should go back to improving my Ruby skills, too.

Java, being rooted firmly in the C tradition, believes that the first number is zero. Arrays and lists begin at index 0. The first character of a String is string.charAt(0). Thanks to the legacy of time.h, Java even believes January is month 0, skewing up the mental landscapes of anyone used to thinking of June as month 6, and December as month 12. (Someone once told me this originated with the desire for C programmers to be able to map easily between a numerical month, and an array of named months without wasting the first... er... zero-th element of the array).

It therefore came as something of an annoyance to me when, years ago, I discovered JDBC starts counting at 1. I've lost count of the number of times I've been caught out because the first substitution parameter in a PreparedStatement isn't zero, and neither is the first element of the ResultSet. But I've gradually got used to this, annoying as it is.

Then today, I discovered java.sql.Clob#getSubString(long, long). Let's ignore for a second the fact that the java.lang.String#substring(int, int) method sets a precedent for “substring” being a single word, with no internal capitalisation. Thankfully, Eclipse's auto-complete has set me free from that particular trap. Let's instead look at this one, little thing.

The offset parameter in String#substring is zero-based. The offset in Clob#getSubString is one-based. What the hell were they thinking? Every single Java programmer, on seeing that method, will assume that it's zero-based without even thinking. And it isn't. Bastards! I don't care which is closer to the ODBC API. I'm sure 99% of Java programmers don't care either.

Once more, with feeling. Bastards!

From a link passed to me by batty, we find Modern Drunkard Magazine's: The 86 Rules of Boozing

34. If you bring Old Milwaukee to a party, you must drink at least two cans before you start drinking the imported beer in the fridge.

...

55. If you think you might be slurring a little, then you are slurring a lot. If you think you are slurring a lot, then you are not speaking English.

JSR-666

  • 7:35 PM

JSR-666 n. The Java Specification Request from Hell. The one that contains all the ideas that will make Java... well... not Java any more.

Usage:

“Java would be much better if you got rid of static typing and checked exceptions.”
“Yeah, that's one for JSR-666.”

Update: Alan Green, the cow-orker with whom I came up with JSR-666, has compiled the initial list of recommendations., including import *, having a default throws clause for all methods, and the complete elimination of NullPointerException. Further suggestions are welcome.

Shellshocked

  • 3:28 AM

Tonight, just before going to bed, I learned of the tragic break-up of the Space Shuttle Columbia on re-entry, and the probable death of her seven crew. To those astronauts and their families, I send my thoughts before I go to sleep. They are brave pioneers who work to push back the horizons of our world. I hope they found some way to cheat death. I am sure if they are confirmed dead, the world will mourn their passing.

Friday, at around half past six in the morning, a train derailed outside Sydney, killing eight and injuring 41 others. If you don't live in Australia, you probably haven't heard of this. They played their part in making our world. These were ordinary people on their way to work.

Today, probably more than one hundred people died in car crashes in the USA alone.

Who do we choose to mourn? How is this decision made? Can we truly care about the whole world, or is it just too damn big? Can anyone truly comprehend, and care for every single person who died today, or would it destroy our souls to try? And is it disrespectful to elevate any of the dead above any others?

To all who live on this earth, take a moment today to recognise what is precious to you. Cherish that now, for we are all mortal.

This is entirely Lonita's fault. The rest of my apartment will have to wait until I've finished tidying, but I thought I'd do the kitchen beforehand, just for all the beer bottles.

An annotated picture of my kitchen.