if ( document.comments_form.url ) { document.comments_form.url.value = getCookie("mtcmthome"); } Otaku, Cedric's weblog: May 2005 Archives

May 25, 2005

SWT/JFace: the story of a success

This short post on the JPreference API of JFace sums up pretty well why SWT/JFace has been gaining so much momentum these past years to create Java user interfaces.

I have been using AWT (and later, Swing) since the very first days, and while I was fascinated by the idea of creating rich interfaces with my language of choice, it was hard to ignore their shortcoming.

First of all, performance took a long time to become acceptable, and even now when we have finally reached this point, the bottom line is still that it takes an awful lot of efforts and expertise to produce an interface in Swing that looks professional and feels native enough.

There are several reasons for this:

  • The MVC  model of Swing is a failure.  It's clever, reasonably-well designed, makes a few needed compromises with the original MVC idea, but it's simply not used.  Maybe it's a matter of education or lack of expertise from the developers, but I hardly see any code that actually adapts the widget models to their own domain objects.  Most of the code I have seen is a set of helper methods converting DAO's to the original models, defeating the separation of view and model.
     
  • Swing is built on AWT, which was not designed to be extended.  Throughout the years, AWT has been retrofitted and patched to support various Swing requirements (does anyone remember the lightweight/heavyweight debate that took years to settle?) but at the end of the day, the pyramid feels cumbersome and shows very little advantages for developers.
     
  • GridBagLayout is an absolute disaster and the perfect example of something that is completely flawed and violates with a stunning regularity the principle of least surprise.  Whatever layout you are trying to write, I am betting that you never reached it before a discouraging number of trials errors (I strongly recommend checking out JGoodies if you want some quality piece of Swing software, and I'll also take this advantage to give a quick shout out to Romain Guy, who has been proposing a lot of very creative Swing ideas on his blog).
     
  • Despite its ambition and purpose, Swing is still lacking "real-world" widgets that would truly save developers valuable time.  The Preferences API above is just an example, but here is another:  wizards.  How come Swing doesn't have any?  I have written several Wizard classes already, and I'm sure I'm not the only one.  No wonder Swing applications still feel clunky and inconsistent.  Another example is the complete lack of integration with native operating systems (e.g. the system tray in Windows).  Sun is finally trying to fix this problem with JDIC, and it's about time.  And it's also way too late in my opinion (maybe we'll get it in Mustang).

SWT/JFace addresses all of these concerns.

Granted, part of it comes from hindsight and learning from Swing's mistakes, but I have to admit my very profound respect for the OTI team, which created an amazing UI framework (of course, Eclipse and the RCP should be added to their credit as well).

SWT/JFace is really the API that doesn't get in the way of the developer and that lets you achieve amazing results in record time.

Are there any drawbacks to SWT/JFace?

A couple:

  • It is not part of the JDK, so you need an additional download.
  • Its non-Windows ports have been criticized for not being of the same quality as it is on Windows (this is something that has vastly improved these past months).

You basically have three options for your next GUI application:  SWT, SWT+JFace or RCP.  I have no doubt that at least one of these options will be the perfect match for your work, so be sure to evaluate each carefully before making a decision.

Posted by cedric at 09:56 PM | Comments (29)

May 20, 2005

The Art of Commenting

Mike Clark wrote an interesting piece on comments, and I have a few things to contribute as well.

Here are some of the practices I follow with regards to comments:

  • I configured Eclipse so that whenever I create a new class, it inserts a JavaDoc comment that says "This class ".  Yup, that's right.  Just these two words.

    I found that modifying templates so they contain fragments of sentences forces a reaction in me.  As soon as I see them, either I go ahead and edit them to complete the sentence, or I delete them completely.  Which is much better than seeing five lines of text saying "This comment was generated in a template.  To configure your template, go to Windows / Preferences /...".
     
  • I like to add comments for closing braces:

      } // for (word in sentence)
    } // if file exists

    I don't know about you, but to me, a closing brace means nothing.  I have no idea what it applies to and while I can obviously put my cursor on it and find its matching pair (Ctrl-Shift-p in Eclipse), it's actually much better to write it down explicitly.  This kind of comment helps me understand the algorithm I am looking at much better and sometimes, even spot bugs right away ("Shouldn't we close the file outside the for loop?").
     

  • There is a big difference between a JavaDoc comment and a regular comment.  This is a point that seems to be absent from Mike's article but it's a very important one.  For that reason, I find it acceptable to be less strict when you are writing a non-JavaDoc comment (you don't really need to supply an @param for each parameter of your method).  I also tend to reserve the /* syntax for JavaDoc comments and multiple // comments for the rest (this is purely a matter of taste).
     
  • I like to comment blocks of code at a time, as opposed to commenting lines.  For example, I will spend two-three lines describing a for loop at the top of the said loop but I will probably not bother adding extra comments inside (there are exceptions to this rule if the loop is particularly complicated, of course).

These are all more or less personal preferences, but there is one rule that think should be applied at all times:

Get in the habit of commenting code that is not yours.

This is not easy.

There is some kind of unsaid rule in the software development world that somehow makes it hard for people to follow this rule.  Think about it:  how would you feel if you see a commit log indicating that someone modified a file that you created and all they did was adding comments?

Chances are you will take it a bit personally...  "Is she trying to tell me my code isn't clean? Or that my comments are not good enough?".

You need to get over it.  There are many reasons why people other than you adding comments to your code is a Good Thing:

  • Your comments show your own bias.  Since you wrote this code, you are making a lot of assumptions on what the reader already knows and you will most likely omit details in your comment.
     
  • Consider this a code review.  Code reviews are fairly rare in my experience, so any opportunity you can have to get somebody else to take a close look at what you wrote and try to actually understand it is a great way to improve not only this particular piece of code but your skills as a whole.
     
  • Somebody else commenting your code goes a long way toward making your code easier to read and evolve in the future.  They are trying to share their perspective on what you wrote and make it available to everybody else.  They are trying to save future developers the trouble they had to go through your code.

So next time it happens, don't take it personally, take a close look at the new comments and if they are not to your liking, work with the person to improve them.  And of course, feel free to return the favor, and if everybody does their part, your code base will end up being easier to read and maintain.

 

Posted by cedric at 12:01 PM | Comments (17)

May 19, 2005

Revenge of the Sith: I needed closure

Note:  you won't find any spoilers in this message.  I am so opposed to spoilers of any kind that I actually never even watch previews of upcoming shows or movies.  Try it, you will be surprised how much more you will enjoy the show.

I watched "Revenge of the Sith" last night and I have to say I wasn't disappointed.  Just like everybody else who grew up with Star Wars as a kid, this movie concludes a process that started twenty-five years ago when I discovered the first Star Wars (which turned out to be the fourth one as I learned only later).

The visual effects of this latest installment are stunning to the point of sometimes being overwhelming.  It seems to me episodes IV, V and VI had to focus more on the plot and character development than their newer counterpart, but there is still a tremendous amount of material in these prequels and the Lucas team played it out perfectly well.

After reflecting over my experience last night for a few hours, I can't think of any gap that this episode didn't cover and, indeed, everything is now ready for the first scenes of "A New Hope".

Who can forget the fantastic opening of this episode showing a minuscule shuttle lost in a dizzying array of lasers as it tries to escape a triangular imperial battle cruiser that endlessly unfolds over our heads?

Leia was right:  Obi Wan Kenobi was indeed their only hope, but the difference is that watching "A New Hope" now will make him look like an old friend.

Any disappointments for this last episode?  Not many, really, but if I have to list a few, I would say that some actors are way too old to make credible laser saber fighters (Count Dooku and Palpatine himself) and the fact that some acting scenes and dialogues are, frankly, embarrassing.

I was also afraid that knowing exactly what will happen to all the characters (probably the ultimate spoiler in a movie) would ruin some of it but I was wrong, since there is still a lot of mystery left as to how the characters became what they are in Episode IV.

But what's really interesting is that none of these negative points really matter.  Yes, George Lucas' spell is that strong:  it's not about the direction, the actors or the visual effects any more.  It's about storytelling.

It's about being nine years old all over again.

Posted by cedric at 11:32 AM | Comments (7)

May 17, 2005

Ant profiling

Eugene is trying to write an ant profiler.  His preliminary results are encouraging but I believe he's only solved the easy problem.

In my experience, ant builds are not slow because they spend too much time in targets (this time is usually incompressible) but because identical targets get run multiple times or or the same files get processed several times.

Here are a few steps that might lead to a good ant profiler:

  1. Provide a way to visualize the graph of dependencies.

    This should be easy enough:  parse all the targets and their depends clauses and show a graphical view of what it looks like.  With some simple graph algorithms, it's also pretty easy to point out extraneous and redundant paths.  

  2. Add finer-grained support in ant's listeners.

    This requires active participation from the ant project but I think it would be worth it.  The current listeners are fairly primitive and do not provide any insight on the internals of each task.  What I believe would be interesting is for each task to implement an interface that lets observers know when a certain file is being processed and when the resulting file is starting and finishing to be generated.  With support for such listeners, it would be trivial to see that the file "A.java" is being processed twice even in the most complex builds.
     
  3. Start identifying a few "ant build anti-patterns" (targets and depends that create extra work)

    When I looked for examples of anti-patterns in my various builds, I came up empty.  It's not that my build files are good (I know they're not), but it just seems very hard to pinpoint exactly what goes wrong as your build files start accreting fat throughout time.

    Also, there are two different ways we can derive information from this stage:  a) by looking at the build.xml (or its DOM representation) directly or b) at runtime, by storing information on the target paths that are being walked by ant and displaying a report at the end.

Can you think of any ant design anti-pattern that will cause a build to take longer than it should?

Posted by cedric at 10:01 AM | Comments (2)

May 12, 2005

Idea for a FireFox extension

While tabbed browsing has considerably increased my comfort in web browsing, I still find that navigation could be made easier.

In a typical session, I have between five and ten different FireFox windows on my desktop, each of them containing one more more tabs.  Like most tab users, I try and keep all the related browsing in the same window.  For example, here are some of my typical main windows:

  • javablogs.com
  • theserverside.com
  • bloglines.com
  • My blog
  • Various JavaDocs
  • etc...

In turn, each of these windows contains tabs with links reached from these main windows.

The problem is that FireFox adjusts the title of the window based on what tab is being displayed, which makes it hard for me to find "the window where I open all my bloglines links".

I was wondering if an extension that lets me change the title of the FireFox window exists?

And if there is no such thing, how hard would it be to create a GreaseMonkey script (or a real FireFox extension) that lets me tell FireFox things such as "If one of the tabs displayed is on *.bloglines.com, then name this window 'blogs'".

Any idea?

 

Posted by cedric at 09:26 AM | Comments (7)

May 11, 2005

We are all Hungarian Notation users. Yes, even you!

I bet that most of your for loops on integers use i as a variable.

And that nested loops use j and k.

When you iterate over a collection, you probably use it, and if you have nested iterator loops, you might consider renaming your iterators to make the intent clearer (itPerson, itAccount).

If you are writing GUI code, you have probably noticed that you need to decline the same word several times to mean "the widget", "the label of the widget", "the callback for this widget", etc...  And you probably came up with your own personal convention to keep your code readable.

Maybe without realizing it, you are using Hungarian Notation. Well, at least, the original Hungarian Notation, the way it was supposed to be used.  Not the newer one that imposed mangling the type of variables into their names.

In a very thoughtful entry, Joel Spolsky explains in details what the original Hungarian Notation was about, and why you should care.

Joel gets it.

He doesn't get everything, though (see below), but he understands the importance of conventions and how appearance of code is more important than it looks.  No pun intended.

A long time ago in a physics class,  a teacher gave me a tip that I never forgot and that I kept using for years on.

It was about making a sanity check on a result.  Physics problems usually require you to manipulate not only a lot of variables, but also a lot of very different concepts.  The solution to a problem is usually a combination of several "dimensions", such as "meter per square second" or "electron volt per square inches".  My teacher suggested that I should always calculate the dimensions of the results on both sides of the equal signs, and that they had to match.  If they didn't, then I was sure I made a mistake somewhere.  If they did match, then...  well, the solution might be correct.

If you did some basic arithmetic in school, you might remember a similar sanity check called "preuve par neuf" in French (interestingly, I have no idea how it translates into English and I'll welcome anyone who can tell me).  The idea was simply to verify that both sides of the equal signs have the same nine modulo.  Why nine?  Because you can calculate it by adding the digits of the numbers involved.  If the sums don't match, you are sure you made a mistake.  If they do...  your solution might be correct.

Similarly, network layers have been using parity checks to quickly verify if a packet was corrupted during a transfer.  There are various ways to do this, but they boil down to a similar idea:  use an inexpensive algorithm to make a quick sanity check on a result.

The original Hungarian Notation aimed to provide a similar hint to programmers:  point out obvious mistakes.

Code that equates a loop index to the height of a window is spelled out in the open for you to see.  No compilers or IDE will catch these errors, but a human might if you used some some convention consistently (come to think of it, it should be possible to teach an IDE what kind of Hungarian Notation you are using so they would flag the errors that Joel describes in his entry...  intriguing idea...  will have to think more about that).

Read Joel's essay on this notation, it will enlighten you.  At least the part on Hungarian notation.

Joel's later points on operator overloading and the evilness of exceptions are definitely more questionable.  And he is so well aware of it that his article include a rebuttal to his own claims.  Now that's intellectual honesty if I've ever seen it.

But still, his points don't make much sense to me and he actually contradicts himself in a few places, such as:

What all these rules have in common is that they are trying to get the relevant information about what a line of code really does physically as close together as possible

Joel fails to see that exceptions actually work toward that goal:  they keep the pieces of code that do the same thing close to each other.  They concentrate the business logic in one place and the error-treating logic somewhere else (which is usually where you want it).

To vilify operator overloading and exceptions, Joel uses the old age argument:

In general, I have to admit that I’m a little bit scared of language features that hide things.

While I sympathize with the feeling, it's clearly not the way we are headed, and the added complexity is simply thrown in because the problems we are solving these days have gotten more complex as well.

C was quite a jump in complexity for assembly programmers, but we digested it because it was necessary.  Between Joel's view of the world where languages should stick to the straightforwardness of C and Guy Steele's view that languages should be "growable", to the point that not only operators should be overloadable but the syntax of these languages and their semantics should be extensible as well, I side firmly on Steele's side.

And if you want to remain relevant in the next decade of software development, you should probably do the same.

 

Posted by cedric at 10:12 AM | Comments (9)

May 10, 2005

An XP interview

An interesting interview of Kent Beck and Tom de Marco, the author of "Peopleware".  What strikes me the most is that while Kent seems to be fairly reasonable, it's clear to me that his buddy is not really in touch with reality when it comes to XP programming (or even programming in the industry, for that matter).  Here are a few selected quotes:

"In the subsequent five years, XP has become mainstream"

"So the parlance I think has become mainstream. Whether the practice has become mainstream, I think it depends on where you go. And a lot of places I go, it is."

"That everybody knows what paraprogramming is."

Reading further down the interview, it looks like "paraprogramming" actually means "pair programming", so Tom is probably trying to coin his own term, a bit like some other people tried to create the term "AO" for "AOP".  Tom also still seems to believe the same old cliches about evil managers who get in the way of developers:

"I think managers in particular are saying, well what the hell am I here for if not to tell a given person when he ought to be testing and when he ought to be coding and when it's time for a build."

and that developers are better left alone:

"And I think XP is a very natural kind of self-coordination where that work, that coordinating work is pushed down the hierarchy."

...  which is totally nonsensical to me.  I am a firm believer that software created by developers only is worthless and that everybody (managers, marketing, UI designers, tech writers, product, etc...) has an important role.  Any activity or technique that isolates these layers from each other is a direct threat to the success of the project.

Fortunately, Kent is here to instill some realism:

"Kent: Well, some of it is. I think of managers as people with more experience, a broader perspective, perhaps more wisdom about what's going on and good people skills."

I credit XP for making developers more aware of testing in general, but from my experience, the few times I have seen some XP at work in companies were through consultants hired on a short term basis because using their full-time employees to do XP was considered a waste of money (and in some way, Kent and Tom seem to confirm this observation since all they do is consult and write books about XP).

An interesting overview overall (if you can set aside the various spelling mistakes), which comforts me in the idea that XP is more talked about than really applied in the real world. 

Posted by cedric at 09:43 AM | Comments (27)

May 04, 2005

A Fortress overview

I was quite excited to learn about the announcement of Fortress, a new language from a team that includes Guy Steele, Common Lisp guru and famous author of the Growing a Language paper.  It's not very often that a new language comes out with a PDF documentation of more than a hundred pages describing both the intent, philosophy and gritty details of the various features.

I was also curious to see how many of the ideas that Steele put forth in his seminal paper he was able to apply to this new language. 

Quite a few, it turns out.

If you are a Java / C# / C / C++ developer, here is what you might want to know about Fortress.

  • Fortress is an attempt to replace Fortran.  I know, it doesn't sound very good, but it's not too bad, really.  While Fortress has an undeniable bias toward a few mathematical constructs (such matrices and the fact that * is optional) and its documentation contains some scary looking words such as "Abelian group", the end result is actually quite pleasing to the eye and features a few pioneering language constructs that are worth a closer look.
     
  • Fortress uses the full extended Unicode character sets, which means you can use all kind of strange characters such as Θ, ←  or ∈.  It's quite surprising at first but you get used to it really quick and I have no doubt that's what all languages of the future will look like.
     
  • Fortress is strongly typed but uses type inference a lot, like Haskell and a few other functional languages.  In other words, you never need to specify a type when the compiler can guess it for you.
     
  • Fortress doesn't have classes, it has object and trait, which is an interesting mix of of the traditional and prototype approaches.  Traits are like Java interfaces except that you can also specify concrete methods in them (a similar concept as the one found in Objective C).  Fortress also has an hybrid keyword called api which is like a trait except that it can only contain abstract methods.  I have to say this throws me off a bit.
     
  • You can use named parameters to invoke methods.
     
  • It supports design by contract with ensures, requires and invariant (I'm not a big fan of DBC myself).
     
  • There is a mysterious dispatch keyword that allows you to select on object types.  Not quite sure what this does exactly, I'll have to get back to it.
     
  • You can mark methods with test.  Again, I'm not quite convinced this kind of thing should be part of a language, but well, I am promoting the use of annotations to do that myself, so I guess it's a small leap of faith.
     
  • Fortress has support for automatic forwarding.  This is very interesting because the way this is implemented is almost identical to the way I suggested doing it a long time ago (in 1998!) in Java.
     
  • Fortress has extensive support for futures and asynchronism.  It goes much further than Java and its thread support, even with the java.util.concurrent package.  Fortress is clearly geared toward making heavy computations, so this makes perfect sense, but the documentation gets a little bit abstract in this area, using sentences such as "asymptotic behavior of parallel code space".  Don't let yourself impressed, there are some truly interesting ideas.
     
  • Finally, Fortress delivers on the promise of making the language "growable", a page from Guy Steele's own book.  The way this is accomplished is by allowing developers to specify entire abstract and concrete syntaxes in Fortress itself, which is quite a tour de force (and as a matter of fact, the documentations shows the Fortress grammar in both EBNF and concrete syntax Fortress notation).

    Even though I have a lot of sympathy for the concerns expressed in Guy Steele's paper about letting the door open to evolve the syntax of a language, I am still skeptical that this is what will make your language stand the test of time.  Historically, languages have come and gone not because of their syntax but because they were no longer semantically adequate to address modern problems.  The only way you could actually make a language that flexible would be by fitting it with a meta-object protocol, but that's a path the Fortress team decided not to take, although their concrete syntax extension might possibly be used to that effect.

Obviously, I don't think Fortress is perfect, and there are a few things I dislike about it.

While I respect immensely the freedom of language authors to experiment and pioneer new concepts or introduce marginal ones, I still think there are a few compromises that should be made.  Some languages sometimes exhibit keywords or constructs that are clearly meant to do exactly the same thing as their predecessors, except with a different name.  Eiffel was notoriously famous for this (e.g. using /= instead of the more familiar != or even <>), and unfortunately, Fortress suffers from some of these vanity problems as well.  It's not as bad as Haskell, though.

For example, Fortress uses the mysterious bounds instead of the more familiar enum, and it differentiates assignment from equality (like Pascal's = and :=).  It also uses do and end to surround blocks (I happen to think that these words clutter the code and that symbols should be used instead, or space-significant indentation, but that's just a personal preference).  Fortress also decided to declare the type after the variable (x : Int), which takes some time to get used to after all these years in C, C++, Java and C#.

Overall, Fortress is a very interesting language that has great potential to succeed to Fortran.  I have a couple of concerns regarding its acceptance as a general purpose language such as Java or C#, though:

  • It only has weak object-oriented support and lacks a few important features (no property support, for example, although this would be trivial to add with the concrete syntax extension).
     
  • Its native support for numeric calculation might turn off the more general developer crowd and make it look marginal.

At any rate, Fortress is an impressive achievement, both in terms of breadth and documentation (Groovy people, please learn from this!).

I'll be keeping an eye on Fortress and I am wishing the team the best luck, they deserve it.

 

Posted by cedric at 08:12 AM | Comments (9)

May 03, 2005

Open house at Google

Google is having an engineering open house this coming Thursday (May 5th).  There will be food, drinks, music and technical presentations.  If you are curious about what Google looks like from the inside and you live in Silicon Valley, email me and I'll add you to the list.

Update: Sorry, we're full, please stop emailing. Please :-)

Posted by cedric at 10:09 AM | Comments (7)

Paint.net

Paint.net is a free replacement for MSPaint.  MSPaint is convenient because available on every Windows machine out there, but it's extremely primitive and for those of us who need a little bit more without requiring all the bells and whistles of Photoshop, it's not really an option.  After searching for a while, I finally found Paint.net which, despite a few glitches on my machine, seems to be very powerful while easy to use.

 

Posted by cedric at 09:10 AM | Comments (6)