Archive for November, 2005

Would you like spyware with that?

I don’t get irritated easily but I have observed a growing trend recently
that is driving me absolutely nuts:  upgrade nags.

Well, to be precise:  upgrade nags without any possibility to turn them
off.

You know, these dialog boxes that pop up whenever you launch the application
and that let you know that a new version of the application is available. 
The arrogance of the authors of these programs is absolutely baffling, and they
should know by now that you don’t get mindshare by forcing products down users’
throats.

Here are the worst offenders as of today:

  • Yahoo Messenger.  It didn’t used to be the case, but their
    recent "Yahoo Messenger with Voice" is obviously so important to them that
    they absolutely want you to install it, whether you have a microphone or not
    (or whether you want it or not).  Look, Yahoo, I like your client and you are welcome to let me know a new
    version is available, but how about a checkbox to allow me to pass on this
    great offer, uh?  Because right now, I am migrating away from Yahoo
    Messenger and urging my friends to do the same.
     
  • Acrobat Reader.  A veteran in the art of irritating users,
    and it’s only getting worse as time goes by.  The most disturbing part
    is that the recent versions are actually worse than the previous ones: 
    longer start-up (do I really need all these plug-ins?  And why would I
    care about all these patents you filed?), pathetic scrolling and window
    management, miserably slow searching.  They must have seen that their
    users were reluctant upgrading, so they found the best way to make you: 
    a forced upgrade nag.  Keep up the good work, guys. 
  • iTunes.  Probably the worst offender.  Why? 
    Because it suffers from the same problems as Acrobat Reader plus the fact
    that every new version seems to restrict your rights on your own songs
    further.  When you upgrade iTunes, you can never really be sure that
    your iPod is not going to be wiped clean of songs or whether some of the
    songs you didn’t buy through the iTunes store won’t mysteriously stop
    playing.  Of course, it doesn’t exactly help either that the Apple forums opted out of Google, so searching for answers to your iPod problems will typically not yield anything. And finally, here is the
    latest offense
    to date.

Any other?

World of Warcraft Methadone

Ever since I started playing World of Warcraft some ten months ago, I have
been hoping for the addiction to end.  It’s a bit ironic to enjoy something
so much that you actually want to get off it so you can return to a more
balanced life, but it’s really how I’ve been feeling these past weeks.  Not that my life hasn’t been balanced:  I think I did
pretty well, especially compared to some of my guild mates who routinely spend
twelve hours in a row playing the game without any bios (warcraftese for
"a break dictated by a biological necessity:  food, bathroom, etc…").

Well, I think that time has finally come.  I can proudly announce that
"I am over World of Warcraft".

Let me explain how I got there.

I have to hand it off to Blizzard for creating a game that is equally
fascinating "in the middle" (levels 1-59) as it is "at the end" (level 60). 
Keeping level 60 characters interested is no small feat, and you need to find
ways to keep them entertained even though they no longer get any experience. 
World of Warcraft does this by providing dungeons of
incredible difficulty that can only be defeated by groups of 10, 20 and even 40
(all group members need to be level 60, of course).  As you can imagine, finding groups to enter
such "instances" (the technical term for these dungeons) is not easy and
even if you might be lucky and find yourself invited to a random pick-up party
for the
Molten Core (one of the hardest instances in the game), you probably
don’t want to join anyway because you really need to play these dungeons with
people you know and trust.

What is the appeal of these instances?  Loot.  Very rare and overly
powerful gear that will greatly enhance your character.  It’s really the
only reason why players enter these instances, which is a bit baffling to me
(and probably one of the reasons why I am finally quitting).

A high-end instance is an intense experience.  Very intense.  Here
are a few points:

  • You need to commit for four to five hours in a row.  Don’t even
    think of quitting unless you have a replacement ready and that the class of
    your replacement is similar to yours (or close enough).  Parties for
    high instances need a very precise balance of various classes (warriors,
    mages, priests, etc…) and tilting this balance, especially in the middle
    of the instance, can prevent the party from finishing.
     
  • You need to be on TeamSpeak.  TeamSpeak is a central server that
    allow groups of people to communicate with their microphones and headsets. 
    You don’t really need a microphone if you’re not a leader, but being able to
    listen to the directions from your leaders and to the talks during the
    fights is absolutely essential.  Regular chats are not fast enough and
    very easy to miss in the heat of combat.  I expected a lot of chaos on
    this channel, but all the players of my guild turned out to be very
    disciplined and they do not talk unless absolutely necessary.  It was my
    first experience of a video game leveraging audio and I was quite surprised
    by how well it worked out.
     
  • A high instance has several "bosses" (featured above is
    Ragnaros, the final boss of the Molten Core, and you’re not even sure that
    you’ll be able to summon him every time) and the preparation to fight each
    of them can take easily twenty to thirty minutes.  I’m not even talking about
    the fight itself, which can also be very long, but just the planning and the
    directions from your leader instructing various groups where to stand, where
    to go depending on how the fight turns, explaining various tactics,
    describing how the boss works and what attacks to expect from it, telling
    you which spells and moves to use which which ones to avoid, sharing "buffs"
    (protective spells that players cast on each other), etc…  By the
    time the fight is about to begin, your head is literally buzzing with the
    information overload, but now is certainly not the time to lose your focus
    because the real work is just about to begin.
     
  • Depending how well you do and how disciplined the party is, the boss
    will finally drop, possibly after a few "wipes" (the entire party decimated)
    followed by a long session of resurrections to bring everyone back. 
    When the boss is defeated, it’s time to uncover the loot and decide who gets it. 
    That’s right.  Each boss typically drops three or four items maximum,
    and since you have forty players, not everybody is guaranteed to get an item
    on a run.  So how do you decide who gets what?  There are various
    systems in place, the most popular one being DKP (Dungeon/Dragon Kill
    Points).  I won’t go into detail on how this system works, but suffice
    to say it involves keeping track of who has gone to what raid, and what
    dropped during these raids.  It’s a fair system that guarantees that
    the more raids you participate in, the more likely you become eligible
    for a rare item.  If you are curious, here is a typical

    DKP standings page
    .

With all that in mind, it should be no surprise to you that a high instance
raid is an intense experience that will leave you sweating.  But boy! 
What a rush!

I went on a few of those runs after finally deciding that the amount of
involvement versus the feeling of reward was no longer high enough for me. 
It was one of the most immersive experiences in a video game I have ever had
(which is no small feat in a career of almost thirty years playing videogames),
but the time has come for me to move on.

So I am now looking for my new addiction, and the winner is…

Ah…  Civilization…  my old Nemesis.

I’ve only been playing for a week so it’s still a bit early to tell if
Civilization 4 will deliver.  All I can say for now is that the ramp up is
pretty tough, especially for a Civilization I veteran such as myself.  But
I’m going to give it a fair chance, even if coming right after World of Warcraft
is certainly a challenge.

So here’s to a fond goodbye to World of Warcraft and the dawning of a new
Golden Age (ah… already using Civilization lingo).

 

The cost of fun

In a recent game review, PC Gamer mentioned that Quake IV, which was released recently, can be completed in about ten hours.  Ten hours.

This made me think.

I must have spent easily that much in my first week of World of Warcraft.  And probably just as much in all the weeks following, for a period of several months.  Which led me to wonder about the cost of entertainment, and how each type compares to each other.

Let’s start with Quake IV.  Ten hours to complete it, maybe another ten hours to do it a second time (some people seem to do that) and maybe twenty hours playing on the multiplayer version, for a total of forty hours of fun.

World of Warcraft… well, it’s actually fairly easy to quantify since the game keeps track of this for you.  Over a course of nine months, I built two character up to level 60 and each of them clocked in at over twenty days of playing.  That’s twenty days of effective play — 480 hours — and let’s add a few hours spent on a few other characters to round it up to about 1000 hours total.

Here is a quick breakdown:

NameUpfront costCost per hourExplanation
World of Warcraft$50 + $15 / month = $18518.5 cents per hour$185 / 1000
Quake IV$50$1.02 per hour$50 / 40 hours
TV Show$30 per month (basic cable subscription)$2.70 per hour$30 / 12, assuming you watch 3 series, each showing 4 episodes per month
Movie (rental)$5$1.7 per hour$5 / 3 hours (movie + extras)
Movie (theater)$10$5 per hour$10 / 2 hours

Of course, there are plenty of other activities we could add, such as sport (mostly free:  basket, volleyball, etc…  and not so free:  golf, scuba diving, horse riding. etc…) and other ways to pass the time (hiking, walking, running, reading, etc…).

Another factor that we should probably add is the "intensity" of these activities.  Not all of them will enrapture you and isolate you from the real world with the same intensity, and you could probably say that World of Warcraft would score very high on that scale while hiking would not.

But the general idea is this:  World of Warcraft, and massively online games in general, have often been chastised for not only the monthly fee they charge but also for charging for the game in the first place.  In light of these numbers, one might actually wonder why they don’t charge more…

 

Annotations and Behavior-Driven Testing

I have been a long-time fan of annotations, and my devotion started with
EJBGen (which was using JavaDoc annotations in 2001, imagine that!), followed by
my involvement in JSR 175 and now, with TestNG.

Annotations make a lot of sense for a testing framework, but once in a while,
I still hear a few people wondering if they are appropriate for this particular
domain.  Not only do I have a few reasons to believe this, but
interestingly, the latest emergence of something called Behavior-Driven Testing
is making this point further.  Here’s why.

JUnit requires your test methods to start with the word "test". 
When you do this, you are actually adding information to
your method, attaching the "metadata" (extra information) that it’s not just a
Java method:  it’s a Java test method.  This is
the very definition of "metadata":  data on top of existing data.  But what are you really trying to achieve?  You are flagging your method
so that it can be found by JUnit.  If you think a little bit about it, this
goal doesn’t have much to do with the name of your method.

Here is another way of looking at it:  what if you are using a framework
that, says, automatically generates RMI stubs for any methods that start with
"remote".  How do you combine this with JUnit?  It’s easy to see that
this approach doesn’t scale very far.

Recently, a practice called Behavior-Driven Testing (BDT) has received some
publicity.  The idea is to use a different terminology for your tests, not
only for your test method names, but also in the way you perform your
assertions.  Here is an example:

public void testAccountIsEmpty() {
  assertEquals(m_account.size(), 0);

Which can be rewritten as:

public void accountShouldBeEmpty() {
  m_account.shouldEqual(0);

I’ll save the discussion on the pros and cons of BDT for a future posting and
observe that the idea of baking the "test" attribute into the method name breaks
down for this approach, proving the point that the name of the method and what
this method means to a particular framework are completely orthogonal ideas.

Of course, the corollary of this observation is that
TestNG already supports BDT 🙂

 

Hani is in da JCP!

Congratulations to Hani for
his election to
the JCP
!

Hani, do us all a favor and be to the JCP what Schwarzenegger is to
California.

Mmmh…  maybe it’s not that much of a compliment, but you get the idea.

 

Westminster Abbey and a mocha

Buckingham Palace
Westminster Abbey

I was in Paris and London this past week, here are a few random thoughts…

  • I tamed jet lag.  I have traveled internationally so
    many times that by now, I have it down to an art. Here are a few simple
    rules:

    * Start shifting your time before leaving your country.  Stay up
    late (very late) and don’t sleep in too much.  Note that the point is
    not really to make yourself tired so you will sleep on the plane (which
    doesn’t help at all with jet lag) but just to start adjusting to your new
    time in your own environment.

    * On your first day in the new country, don’t nap, don’t sit
    (especially on comfortable couches), and don’t go to bed before 10pm.

    Also, try not to abuse coffee:  the more you confuse your stomach with
    unusual quantities of drinks and meals taken at odd times, the harder it
    will be for your body to get used to your new schedule.  Ideally, you
    simply want your metabolism to believe that instead of a 24-hour day, you
    are just going through a 33-hour day and that your sleep pattern doesn’t
    need to be altered to handle it.

    That’s it.  Follow these simple instructions and even a nine hour time
    difference will have absolutely no effect on your body.
     

  • I flew on one of Virgin Atlantic’s latest aircrafts on the way back, and
    it featured the best entertainment system I have seen on an international
    flight by far:  about fifty movies to choose from, entire seasons of TV
    series, news, games, etc…  It’s all there.  You can also pause,
    rewind and fast forward everything at leisure.  Absolutely fantastic if
    you’re not the reading type on planes.
     
  • Cell phone interoperability has come a long way and works close to
    perfectly now.  My trusted 6630 (which took the pictures above) worked beautifully and never lost GSM
    connectivity.  I actually travel with two phones and interestingly,
    they picked two different roaming carriers while in France (Orange and
    Bouygtel).  This is quite puzzling since both are Cingular, but it was
    a good opportunity to experiment.  No surprise there:  both phone
    calls and SMS worked seamlessly, the only glitch being that one of the two
    carriers refused to give me caller ID.  Not a big deal.

    I also experimented with sending SMS messages back to the US and between England and France,
    and everything worked fine.  Better:  even EDGE performed beautifully
    and allowed me to connect to the Internet through the Bluetooth modem while
    riding the Eurostar on my way to London (except in the tunnel, of course,
    but my phone quickly regained coverage when we came out and latched on O2 on
    the British territory).

Maybe we really live in a connected world after all.
 

The future of source files

I just finished reading a
very interesting
article
by Gregory Wilson that covers many issues that I feel strongly
about.  In a nutshell:

  • UNIX shells are a wonderful, albeit aging, invention.
  • COM is a very powerful framework that has enabled a formidable ecosystem
    of innovative technologies on the Windows platform.
  • No matter how hard we try, we don’t seem to be able to solve problems in
    only one language.
  • Even worse, we are increasingly mixing different languages in one source
    file.

My first observation is that this article fails to mention
MSH, Microsoft’s next
generation shell, which expands on the first two points by providing a type-safe
shell that formalizes the data that is exchanged through connecting processes. 
No more arcane and non-standard command-line switches, or hacks using regular
expressions to parse the output of all these tools.  MSH is a fascinating
tool and I’ll save its description to a future entry.

Gregory Wilson also makes the point that in the future, languages will be
stored internally in a neutral format and be shown to developers using their own
preferences.

A few weeks ago, I started working on an Eclipse plug-in that would allow me
to have properties in my Java files.  The following code:

private String m_name;

public String getName() {
  return m_name;
}

public void setName(String name) {
  m_name = name;
}

would appear in my editor as:

+ property String Name; …

This line would be folded by default and would be replaced with the full
declaration above if expanded.

How does this relate to the article above?  Quite directly:  with
this plug-in, I am transforming the Java syntax into my own.  I am using
the Java source as an internal format and using an IDE to present it to me in a
form that I find easier to read.

It doesn’t have to stop there.  Maybe you don’t like Java’s semi-colons
and braces and you prefer Pythons’ significant spaces instead:

if (m_suiteConfigurationFailed)
  result = false
else
   for(Object targetInstance : instances)
     m_method = new InvokedMethod(targetInstance
   result = true

As for Wilson’s basic point and the idea that all the programs in the
world can be expressed in XML and shown in a user-defined way, I am still very
skeptical.  It’s not so much about the read-only view but more about the
way people write programs.  New languages keep being created on a weekly
basis, and some of them bring new concepts with them, which won’t be adequately
captured by this universal XML format without modifying its semantic, which
brings us back to square one:  representations that are incompatible with
each other and programs that can only be read or saved with a specific version
of the representational language.

Another problem with Wilson’s approach is that developers spend a lot of time
reading other people’s code, which mandates the existence of a language that
everybody understands.  The tricks described above do not alter the Java
source, and the physical file can not only still be parsed and compiled by
javac
, it can also be understood by any Java developer.

But I believe there is some hope and some promise, and in the meantime,
nothing stops us from taking baby steps toward this destination, such as the
Property plug-in I described above.

How about you:  how would you like to see your Java programs
represented?

 

Podcast

My podcast with the JavaPosse is now
available.

 

C# 3.0 Score Card

To make good on my
threat
, here are a few thoughts on the
C# 3.0 features that I
find interesting, along with a grade and a few thoughts:

Implicitly typed local variables:    A

I have been asking for this feature in Java for years.

Why do I need to
write:

Account a = new Account();
Employee e = (Employee) employees.get("John")

Instead of

a = new Account();
Employee e = employees.get("John")

Can’t the compiler figure this out for me?  Of course, it can.

Generics solve the second case, but they add more type inference envy than
ever:

List<Map<String, Name> employess = new ArrayList<Map<String, Name>>();

Surely we can do a bit better than that, right?

Well, that’s exactly what type inference will bring you.  Combine strong
typing with a strict application of the DRY principle and you get the best of
both worlds.

Extension methods:    C

This feature lets you add methods to a class outside the definition of that
class.  The syntax is a bit peculiar:  you add this to the first
parameter of your method:

public static int ToInt32(this string s) {
  return Int32.Parse(s);
}

I prefer Ruby’s syntax for this:

def string.toInt32()
  …
end

Note that this feature doesn’t break encapsulation:  extension methods
don’t have access to private fields or methods of the class they extend. 

As for the feature itself, I have to admit it frightens me somewhat (both in
Ruby and C# 3.0) because it becomes really hard to know exactly the
contract that classes abide by, and also where the extra definitions are coming
from.  I have to admit that over the years, I have grown quite fond of
Java’s rigid "one public class per file" rule and I’m afraid that extension
methods might resurrect the C++ header nightmares that haunted C++ programmers
for decades. 

On the other hand, this kind of
extensibility opens the door for some very interesting tricks, such as the ones
used by Ruby on Rails to exercise its magic (more on that in another post).

Time will tell.

Lambda Expressions:    B+

I have no doubt that functional programmers are screaming in frustration to
hear the term "lambda expression" hijacked to mean "closure".  Let’s put
the intellectual debate aside and observe that closures are extremely useful. 
C# already had a head start over Java with delegates and is now pulling further
ahead with closures.  Let’s hope Java will follow suit.  The C# syntax
is fairly straightforward:

(int x) => x +
1

defines a lambda
expression that accepts an integer parameter and returns that parameter
incremented by one.  You can then pass this lambda expression around as
real object.  I am quite looking forward to using this feature more.

Query
Expressions:    C-

This feature is
also referred to as LINQ for "Language Integrated Query".  The idea is to
allow a certain subset of relational language inside C#:

customers.
 
Where(c => c.City == "London").
 
SelectMany(c =>
      c.Orders.
      Where(o => o.OrderDate.Year == 2005).
      Select(o => new { c.Name, o.OrderID, o.Total })
 
)

If we have learned anything from Java’s struggle with
object-relational mappers, it’s that embedding SQL in your code is usually a bad
idea, so I’m having a hard time seeing the point in furthering the practice by
making it a syntactic part of it.  I am predicting a very grim future for
this feature.

Object
Initializers:    B+

This feature
helps reduce the clutter of your classes by waiving the declaration of simple
constructors:

public class Point
{
int x; int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
Point p = new Point { X = 0, Y = 1 };

In this example,
Point declares two properties but does not include any constructor that accepts
either of these properties  Yet it is
possible to create a Point object and to initialize these properties in
one statement.  Quite a relief from the verbosity of this.name = name that
plagues Java.  Notice also how well this feature plays out with C#
properties (another top priority on my Java wish list).

Conclusion

There are so many new features in C# 3.0 that
statistically, you are guaranteed to hate at least half of them. 
Interestingly, feature excess has certainly not dampened the popularity of C++,
quite the contrary, so if Microsoft can guarantee that C# 3.0 will be completely
backward compatible with C# 2.0, I am predicting that it will have a great
future.   And a lot of detractors.