JRT

July 31st, 2004

James Strachan puts forward a proposal that Sun opensource the standard Java libraries and I see no problems with it. In general I don’t think we’ll see all the benefits James predicts from it though we would see some. In particular I want to point out one benefit that James claims we’ll get but that we definitely won’t get:

more eyeballs are now looking closely at the code

This is the biggest advantage opensource proponents put forward for opensourcing any code but it just doesn’t apply to Java. Why not? The source code to the standard Java libraries are included with every copy of the JRE. You can already go and inspect the source code, find bugs and submit patches to Sun. The fact is, most people can’t be bothered. They have real work to do and don’t want to be wasting time analyzing the source code for the library their using, they just want it to work. When it doesn’t work then people tend to turn to the source and people are already doing that.

I also don’t believe that people really want to write Java code that can run on the .Net platform. Java has always suffered from people feeling that it was second rate due to it’s cross platform nature. This is true to some extent, when writing any cross platform code you inherently make it harder to use the platforms native resources due to the extra layer of abstraction. Why would you use the .Net platform when all of the extra functionality it would provide (like tie-ins to word, infopath etc) wouldn’t be available from Java (because they’re not cross-platform). You’d have to use JNI or similar to call “native” .Net code and so you have to learn C#, the .Net libraries and their toolsets etc.

Also, opensource developers who are refusing to use Java now will refuse to use Java then. Read some of the blogs coming out of OSCON at java.net and you’ll realize that the majority of the opensource world is just unreasonably bigoted against Java. That’s okay though, I’ve grown to really dislike the GPL anyway.

Why You Shouldn’t Employ “Great Hackers”

July 31st, 2004

This article entitled “Great Hackers” really pissed me off. It is just so far off-base that it’s annoying. It’s not the kind of article that is generally wrong on facts, but just wrong on intentions and the concepts of what’s good and what’s bad. There are a few really, really stupid and outright wrong statements in it though. The worst of these is:

The programmers you’ll be able to hire to work on a Java project won’t be as smart as the ones you could get to work on a project written in Python.

That statement referenced a footnote as well which I thought might point to some scientific survey of Java programmers vs Python programmers so that the statement at least had some backing. Sadly, the footnote was:

[2] When Google advertises Java programming jobs, they cleverly require Python experience.

Honestly, doesn’t everyone know that real programmers code in C? Smart programmers aren’t Java hackers, smart programmers aren’t Python hackers, smart programmers use the best tool for the job. Sometimes that’s C, sometimes that’s Java, sometimes that’s Python and sometimes it’s a pen and paper.

Also:

Great hackers also generally insist on using open source software.

Maybe, but probably not. Great programmers use the best tool for the job regardless of whether it’s open source or not. Furthermore, programmers who aren’t in the opensource world tend to be unknown and you definitely wouldn’t know if they were great or not because you most likely won’t see the result of their work.

My biggest complaint about the article though, is that it espouses “Great Hackers” as something to aspire to. Great hackers have their place - they are really good at quickly creating prototypes because they are just so efficient at writing code. The golden rule of prototypes definitely applies though: always throw it out. Great hackers are dangerous because they write code so rapidly and are so focussed on doing what they enjoy that they don’t stop to design, document and test carefully. In software development, writing the code is the easy part. The design is the critical part to get it working correctly, the documentation is critical to keeping it working correctly and the testing is the part that takes up most of the time (while being necessary because of the problems introduced in the coding stage).

So when we look at a project the thing we least want is someone who is obsessed with writing code and who makes a habit of rushing in and implementing code without first designing it and rushes off to the next thing before they’ve properly documented and tested it. In short the worst advice you could give someone who wants to be a great programmer is:

make the following deal with yourself: you never have to work on boring projects (unless your family will starve otherwise), and in return, you’ll never allow yourself to do a half-assed job.

Paul Graham said that was the way to become a great hacker because:

All the great hackers I know seem to have made that deal, though perhaps none of them had any choice in the matter.

Which is precisely why I wouldn’t ever hire a great hacker. I’ll hire the great software engineer instead.

Dependencies

July 29th, 2004

I’ve never understood Java programmers attitudes to dependencies. The Java runtime and libraries was designed specifically to allow cross-platform deployment and increase compatibility. Write once, run anywhere.

What confuses me then is this obsession Java developers seem to have with being incompatible or rather, using the absolute bleeding-edge, never released, not available anywhere version of stuff - particularly the JRE. Now certainly Java is unusual in that it is rapidly developing. Not only that but the language, the runtime and the libraries are all tied in together so if you want to live on the bleeding edge with one you have to live on the bleeding edge with them all. Contrast this with the C world where the language is effectively static, the standard library is minimal and evolving relatively slowly and the “runtime” (I’m thinking of the ABI) is fairly static (if platform specific). It’s not often that C programmers have to make a decision to update to the latest version and it rarely impacts deployability if they do. Most of the time if a C program requires a specific version of a library it just statically compiles it.

In the Java world however, people are always pining for the latest enhancements. Suddenly generics are a huge deal when everyone’s been getting by without them just fine for years. Suddenly it’s too much effort to work around bugs in the libraries and it’s better to just force users to upgrade.

Frankly, that’s simply not good enough.

If I develop an application for Windows, I have to decide which versions of Windows I’ll support. I could use APIs that are new to Windows XP and thus tie my application specifically to it, or I could not use those APIs and let any Windows version run it. Better yet, I could design my system in such a way that I can optionally use those APIs if they’re available and fail gracefully otherwise. C programmers are really good at this, most likely because they’ve spent so much time trying to write C code that’s cross platform (it’s possible, but you have to be good at doing this kind of thing).

Unlike C, Java actually makes it easy to optionally use APIs because everything is dynamically bound. Consider the class:

public class MyCoolClass {

    public MyCoolClass(boolean doStuff) {
        if (doStuff) {
            com.apple.ewt.Application.registerPreferencesListener(this);
        }
    }
}

What happens if the class com.apple.ewt.Application isn’t available? If doStuff is true obviously a ClassNotFoundException would be thrown, but if doStuff is false no exception will be thrown and the missing class will never be noticed. Now clearly, if you change doStuff to something like System.getProperty("mrj.version") != null you’ve just implemented an optional dependency that works on Mac and is ignored elsewhere.

Better than that though, if you know a little about ClassNotFoundExceptions, you can just catch the exception and carry on with life. In C as far as I’m aware you’d have to jump through hoops or use compile time ifdefs to achieve the same thing. Why then don’t Java developers take advantage of this?

The other thing that really annoys me about a lot of Java developers is this concept of certifying a specific JRE version and only running on that. C programs don’t do that, why should it be okay for a Java program to? Again, if I write a standard windows application, my users would expect that it continue to run even if they upgrade to Windows Longhorn, despite the fact that Windows Longhorn didn’t exist when I wrote the program. Sure, sometimes unexpected things happen and software will break in that situation, but why would you not even attempt to anticipate future versions, or past versions? If I already have a copy of the JRE on my system, I should be able to use it to run your Java application. If your Java application has a good reason to require a more recent JRE (and there are plenty of reasons) then yes I may have to upgrade my JRE. If however, your Java application just specifically wants JRE 1.4.2_01 and won’t run on anything else that’s a sign of poor programming. Even worse, is forcing me to install a second copy of JRE 1.4.2_01 even if I have that exact version on my system. The JRE is a shared library, just like libc is - use it!

There’s been a lot of talk recently about Java on the desktop and how Java has to beat .Net or it will disappear off the face of the earth. The way to do that isn’t to improve the language - it’s proven technology that’s widely adopted now. The way to do that isn’t to provide a million different libraries regardless of how good they are - Java already has arguably the best library support around. The way to do that isn’t to provide the best developer tools - there are tons of developer tools out there already and they’re really good. The way to do it is to show people that Java applications can be top quality, well engineered, robust, reliable and fast. If people can see quality software developed in Java - not libraries, not developer tools, real end user software - then people will start to respect Java and it will be appealing to managerial types and pointed haired bosses. Naturally having good tools, libraries and language features can help to create great end user software but the end goal has to be to create great software that actually does something useful, instead of just provides the basis for someone else to do something useful.

Am I saying that there is no good Java software out there? Absolutely not. There’s some great Java software around and there continues to be more and more developed - that’s great! Unfortunately, there’s still far too many Java developers who are maximizing their own convenience instead of the convenience for their end users and that’s not the way to write good software.

In summary, write robust software. If adding a dependency provides enough benefit to your users to outweigh the problems they will have in acquiring that dependency then go ahead and add the dependency. If however you’re adding the dependency purely for your convenience or because it’s cool and new, stop and think about why you’re writing your software, who you’re writing it for and why they would want to add that dependency to the software. If you can’t justify it to the user, don’t add the dependency. Mostly though, write robust software - it should be able to deal with things suddenly changing underneath it because even if you ship a specific JRE version, the underlying OS will change and that will eventually catch you out.

Double-Plus Good

July 27th, 2004

I’ve been following the JDNC project recently and along the way mentioned that it might be nice to combine the authorization dialogs for WebStart applications that have multiple jars signed by different certs into a single dialog to make it more user friendly. Mark Davidson who seems to work at Sun (I assume on the Swing team) promptly responded that he’d spoken to a WebStart engineer about it, logged an RFE for me and said the WebStart guy was going to talk to the security guys about it during the week.

That’s of course no guarantee that it will actually be implemented anytime soon (or any time at all) but it’s nice to at least know that the message got through. Particularly impressive is the fact that I wasn’t even trying to get a message through, just spouting ideas off the top of my head.

It’s generally been very good to see the Sun engineers working to involve the community on JDNC, I had initially thought that JDNC would be a “token” opensource project where Sun employees still control everything but make the source code available. I’m very glad to say that I was wrong about that, there is definitely a strong effort being made to get people involved and already a number of knowledgeable folks from outside are getting involved and providing some very good advice.

Linux’s Curse (Again)

July 25th, 2004

The story so far:

  1. Preston Gralla commented
  2. I commented
  3. Brian McCallister commented
  4. I commented again
  5. Brian McCallister commented again

At least I think that’s how it went.

Firstly, Brian was right to call me on my use of cygwin to bring UNIX capabilities to Windows. It’s not in the default install, it’s not at all obvious and 99% of Windows users will never even hear about it. As Brian says, “if you don’t use it, you don’t learn it”. So if we conceed that the command line is a killer attraction then Linux has it’s big advantage over windows.

That’s where I think Brian and I may disagree. First let me start by saying that the command line is great, it’s an incredibly powerful tool with a lot of really great advantages. It does however require a lot of learning and it’s not once off learning either. The command line requires you to constantly learn - every new task requires research to find out what command does what you want. Then you have to constantly remember all these different commands so that you can use them when you need them. Nothing is obvious, nothing is intuitive. Everything is powerful.

This is a paradigm thing — the drive to ubiquitize computers required them to have an interface comparable to that of a toaster. Now that they are ubiquitous, lets bring back the idea of a powerful interface. Please.

I agree that we need to make user interfaces more powerful and let people do more with their computers but don’t throw the baby out with the bath water. People are no more capable of learning interfaces today as they were 15 years ago. The ubiquity of the GUI does not make it easier for people to learn the command line, in fact it makes it harder due to the unlearning required. Having a command line available with powerful tools is great for advanced users that want to get into that but its still not an option for the vast majority of computer users because they will never get enough benefit out of it to justify the learning cost. Furthermore, the learning cost will be excessively high for casual users because they will continually forget the commands that are available to them.

So how do we reconcile the two goals - having a simple interface and providing full power to advanced users. Most people will suggest creating two interfaces, one for novices and one for advanced users (the novice interface is usually called a “wizard”). This is outright bad user interface design. Jef Raskin provides the best argument I’ve seen on why this is bad user interface in The Humane Interface but sadly I don’t have a copy at hand to give an exact reference. Essentially though the argument is that instead of users having to learn one interface, they must now learn two to be able to use the software. When they first start using the program they are a novice and learn to use the wizard interface. Then they become more familiar with the program and consider themselves advanced so they switch to the advanced interface. Unfortunately once they change the interface they are no longer advanced users - they are completely new to the interface and are in fact beginners. All the learning they did with the beginner interface is worthless and they have to start from scratch with the advanced interface.

Worse still, the advanced interface will almost certainly have been designed with “these are advanced users in mind, they’ll work it out” in mind and is thus much more difficult to learn that it should be.

The other big problem with having two interface modes is the amount of extra developer time that is required to achieve it. That time could have been better spent making the advanced interface easier to learn.

How does this relate to the GUI vs Command line debate? Firstly it shows a weakness in interfaces like Linux where you can do a lot with the GUI but quite often have to switch to the command line, as well as a weakness with Windows where you can do a lot with the command line but often have to switch to the GUI. It’s also a weakness with OS X both ways (some things are GUI only, some things are command line only). More importantly though it explains why we can’t expect people to learn a command line interface now any more than we could when computers first got started.

So how do we make things more powerful while keeping the baby firmly in the bathtub? The first thing I’d point to is AppleScript which is an awesomely cool way to bring some of the power of the command line to the GUI. The ability to pipe one program into another is realized through AppleScript and in fact extended much beyond what the command line pipes can do. AppleScript is shell scripting for the GUI.

AppleScript however is difficult to learn and the language is awful but these are implementation details - the idea itself is still sound. The biggest problem with the AppleScript concept though is that you effectively always have to write a shell script which involves firing up the script editor. Too slow.

What if we mixed the concept of the GUI and the command line together though? Most of the time you’re in the GUI just like normal because it’s easy to use and for the most common computing tasks it’s the most efficient way to do things (how many sighted people surf the web exclusively from lynx?). When you need the power of the command line though you hit a key combination and a command line pops up to allow you to write AppleScript snippets (though in a more intuitive language that AppleScript).

Oddly enough, HyperCard contains pretty much this exact interface. If you hit Apple-M in a HyperCard stack, the message box pops up and you can enter any command you like to control that stack, another stack or even execute an AppleScript.

One key thing here though is that it’s not a terminal window that pops up, it’s a floating window that by default operates on the current application. So if I’m in Microsoft Word typing away and I think to myself:

“I need to insert all the jpg images of my charts into this appendix”

today I would have to click “Insert->Image…->From File…->chart.gif” however many times but with the built in command prompt I’d just hit the magical key combination to bring it up and then “insert /Users/aj/Documents/charts/*.gif” and let Word do the rest. Note that insert would be an AppleScript command defined by Word and tab completion is a necessity.

Similarly, if I wanted to attach a zip archive of a particular folder to an email, I’d bring up the command prompt with a keystroke and enter something like “attach `zip /Users/aj/Documents/emailDocs`” or better “zip /Users/aj/Documents/emailDocs and attach it” which is much more HyperCard like.

That scheme combines the power of command lines with the power and simplicity of GUIs.

Coming back to Brian’s comments though:

The huge thing linux has that nothing else does is that it provides this interface, integrates everything with it, is free to obtain, straightforward to set up, and available right now.

Linux provides a command line interface sure, so does OS X and Windows (though the DOS command line is pretty ordinary). Linux is free but that’s not really a consideration because the cost of the initial computer set up is dwarfed by the amount of costs associated with running it. Besides I want good software not necessarily free software (though I’d be most happy if it were good and free). Linux is available now but so is everything else that’s currently available (oddly enough). Linux is getting a lot easier to set up but it’s definitely not straight forward in many cases. Most people who try installing linux seem to have at least a few issues but I agree it’s nothing insurmountable.

So we’re left with the integration of Linux and the command line. Frankly I wouldn’t consider it integrated very well at all. Sure a terminal emulator is readily available and pretty obvious in Linux interfaces by default but the world of command line mostly stays in the terminal emulator. There are very few GUI applications that really integrate the command line and certainly GNOME and KDE don’t. If the command line is really Linux’s killer feature, it needs to be put to use a heck of a lot more, right throughout the system. I should be able to tell Mozilla to send the currently selected text of the web page through ’sort’ and show me the result. I should be able to select a folder in KDE and run grep or zip or grep -l ‘Vector’ **/*.java | kdeSelect and have all Java files inside the selected folder which contain the word Vector become selected in KDE. That’s integration and that’s not available in Linux as far as I know.

That’s the kind of innovation that Linux is missing and it would make Linux more powerful not less powerful.

Update: I just noticed that Tyler Mitchell was talking about “How do you bridge the CLI vs. GUI gap in app. design?” which I think I just answered so let me throw a ping over that way too. Many of the comments there are interesting as well.