June, 2004

  • Eric Gunnerson's Compendium

    How an idea becomes a C# language feature?


    In a recent email, a customer asked for a delegation feature. He wanted to do something like (purely theoretical syntax):

    class MyClass: ITest
        MyHelperObject o: ITest;

    so that he could delegate the implementation of the interface to a helper object, and have the compiler automatically generate the interface implementation methods.

    My response was that we had talked about this several times in the past, but hadn't been able to come up with a syntax that worked well.

    This is a not uncommon state for us - on several occasions in the Whidbey (excuse me - “Visual Studio 2005”) design process, we tried to come up with a syntax that allowed the user to declare a trivial property (backing store, trival getter and setter) with one bit of syntax, but weren't successfull.

    I thought I'd talk about that process to give you some insight on how we approach things. I can't be exhaustive with all of our considerations, mostly because we don't really operate that way (there isn't a set checklist). If you have a question on a specific feature, I am happy to consider talking about other features and decisions - see the “suggest a topic” hard link on my main page. Just note that my success rate on actually covering such topics is not exemplary. Also note that I make no attempt to answer questions in the order asked.

    The process is fairly organic, in that the steps I list don't happen sequentially, and they are often iterative. Despite the length of this post, I've simplified what goes on significantly.

    Sniff Test

    We start with what I'm going to call the “Sniff Test“, which is basically the highest level triage to determine if we think such a feature is something we would ever consider for C#.  Some features fail because they don't fit the language philosophy, some fail because there's no way we could ever express them in syntax.

    Scenario Exploration

    Our next level of attack is looking at what user problem we're trying to solve. This typically involves us writing down (or up, on the whiteboard) the code that users are currently writing. Sometimes this is limited to the most common scenario, sometimes we'll cover several scenarios - it all depends on what we need to know. This often happens iteratively with the next step.

    Syntax Iteration

    If we've gotten to this step, we're usually fairly convinced that there is a user need. We don't yet know if there is a language solution to that need. In this step, we'll start talking about what we could do in the language to make the developer's life easier.

    This step typically works with Anders writing on the whiteboard while the rest of the design group gives suggestions and feedback. When we hit on a promising approach, we'll explore it for a bit to see where it leads us, contrast it to other approaches we could take.

    In this step, we're asking questions such as:

    • Does this new syntax cover the important scenarios?
    • Does it really make the user's life easier? (new syntax is not a panacea - each new feature adds complexity)
    • Is this syntax unambiguous? Is it possible for the parser to correctly deal with this new feature in the presence of all existing features? (this is a very limiting area)
    • Would this be a breaking change for existing users? (Adding new keywords are examples of breaking changes, but it's also common for new language ambiguities and/or differences in behavior to show up because of new features)
    • Does this feature fit the philosophy of the language?
    • How will this impact tools? Can IntelliSense deal with this?
    • Is this a language feature, or would it be better done through an API, or through the IDE?
    • How have other languages approached this? Has their approach been successful?
    • Does this require new features in the runtime?
    • Does this require work in by other languages?
    • What Microsoft teams would use this? Are they on board to use it?

    In a single session, we will sometimes decide to do a feature and sometimes decide to not do a feature, but more typically we'll decide that we need to discuss it more. We go away and think about it, gather feedback from the people who read our language notes and those closest to the scenario, and then revisit it in a future meeting. A lot of the iteration is around exploring all the corner cases (some of which don't come up until implementation) and making sure the feature is well defined, still does what we want it to do, and still is in the best interests of the developer.

    It's not uncommon for us to change our minds on the details of a feature, or even to decide upon reflection that we need to either reduce or eliminate a feature.

    Structured Feedback

    If we've gotten to this point, we're fairly sure that we want to have the feature, and typically have an implementation (though not always). We use feedback with the C# Customer Council (a small group of customers who we work closely with), and the C# MVPs (we've done a little with the MVPs in the past, we'll be doing more in the future) to see what their perspective is on the feature.

    This is also the point where we work with the ECMA standards body to talk about our proposal, though it's often difficult to align the schedules of the standards body with product milestones.

    There may also be internal Microsoft presentations at this point, depending on the feature.

    Many times the feedback is positive, but sometimes it causes us to refocus the feature, and there have been language features that we cut due to feedback at this point.

    Manufacturing and Shipping

    If we've gotten this far, the feature is in the language, and often implemented. The remainder of the work is to polish the implementation, finish the testing (sometimes testing is concurent with implementation, sometimes it lags a bit - it depends on the type of feature and our resource constraints), do the spec, and discuss how we'll be presenting it to customers.

  • Eric Gunnerson's Compendium

    Risk analysis and estimation...


    I hadn't planned on writing a followup on my risk post, but one comment compelled me to write some more. I hope it isn't too preachy.

    J writes:

    My girlfriend is a doctor. She deals with an inordinate number of motorcyclists every day, from every walk of life. The actual level of risk appears to be very high from the evidence I've seen.

    n the final statement, J is asserting that the risk is very high, and he's also asserting that he's basing his conclusion on evidence. There's also an implicit assertion that his conclusion applies to me.

    I believe that is an unsupported assertion, and I'd like to discuss why.

    The branch of science that deals with risk analysis is know as epidemiology. To pull a definition from a state website:

    "Epidemiology is the study of the occurrence and distribution of illnesses and injuries in human populations."

    If you read a research paper that says something like, “smoking increases your chance of lung cancer by 45%“, chances are that the work was done by an epidemiologist.

    The reason that we do studies in the first place is that it's well known that drawing conclusions from individual experience is often problematic. The whole point of the scientific method is to approach things in an objective and repeatable manner (which doesn't always happen, but that's another subject).

    Just to pick a few of the factors that could invalidate J's conclusion (which I'll restate as “Eric shouldn't ride motorcycles because my girlfriend the doctor see's lots of injured motorcyclists“) (and I should note that I'm not asserting that any of these factors are valid or invalid, just listing what are possible sources of error):

    1. The doctor may be filtering based on preconception of motorcyclists being more risky
    2. The doctor may be giving a summary that is weighted towards more injuries than actually occur
    3. The hospital may get a higher percentage of motorcycle injuries than other hospitals in the area.
    4. The motorcyclists in the region may ride more miles than in other regions.
    5. The region around the hospital may have a higher percentage of motorcyclists compared to a larger population
    6. The average motorcyclist age in the region may be younger
    7. The region may have less effective motorcycle safety training programs
    8. The region may have motorcycle dealers who focus on selling more powerful motorcycles
    9. There may be motorcycle clubs who increase the incidence of risky behavior
    10. Law enforcement may not be enforcing against risky behavior.

    Because of factors such as these, anecdotal data isn't very useful to draw conclusions from (though it is useful to come up with good research topics). You need a real study that looks at motorcycle injuries, looks at the causes of those injuries, looks at the demographics of the situation, and then does some analysis to identify correlations between risk factors and injuries.

    (Aside: Epidemilology is a requirement when you're looking at low-level effects, such as environmental cancer rates, danger from EMF radiation, etc. If not, you can't separate clustering due to random distribution (which is by definition not uniform) from a real effect))

    So, once you've done that research, you should have a lot of information saying how much more likely motorcyclists are to be injured or killed based on a number of factors. And then you can apply those risk factors to a specific situation, and come up with an estimate on how risky an activity is compared to a different activity.

    The literature isn't great in this area, and more study is needed. Many motorcycle accidents come from the actions of other drivers, but I don't know of a recent good study in that area. On single-vehicle accidents, we have the following:

    This study states that on a per-mile basis, a motorcyclist is 3x as likely to be injured, and 16x as likely to be killed. But it also lists some risk factors (look to the study for all of them):

  • Helmet use among fatally injured motorcyclists below 50 percent
  • High blood alcohol levels are a major problem among motorcycle operators
  • Almost two thirds of the fatalities were associated with speeding as an operator contributing factor in the crash
  • Almost 60 percent of motorcyclist fatalities occur at night
  • Braking and steering maneuvers possibly contribute for almost 25 percent of the fatalities
  • Almost one third of the fatally injured operators did not have a proper license
  • I always wear a helmet. I don't drink before I ride. I rarely ride at night. I'm well trained and understand how to properly brake and steer, and I practice a bunch (or I did when I rode more). I have a proper license.

    So I don't have a lot of the risk factors that the accident-involved motorcyclist has, so it's unlikely that the 3x and 16x factors apply to my risk as compared to the general population.

    Of course, my risk as a car driver is also lower because of good habits, so the relative factors could be the same, or could even be worse.

    So, what's my point in all of this? Well, two things.

    The first is that many people make the mistake of assessing risk based upon the overall societal attitude towards a activity and/or anecdotal data (“I knew a guy who...“) rather than any factual basis. If you to to an emergency room with a leg injury, you will get a different response based on whether you say you were skiing or skydiving.

    My second point is that it takes a good study to tell you how you can reduce your risk, so being better informed really pays off.

  • Eric Gunnerson's Compendium

    Grouping classes in an assembly


    This useful bit of information crossed my desk today:

    When it comes to packaging in separate assemblies, remember that you pay a fairly large performance hit on an assembly load. An assembly should really be considered a unit of security control, independent versioning, or contribution from disparate sources. You might consider placing code in a separate assembly if it is used extremely rarely, but probably not.

    Here are some pointers from the "Designing .Net Class Libraries" course:

    Factor functionality into assemblies based on:

    - Performance - There is overhead in loading each assembly. All other things being equal, the fewer assemblies an application loads, the quicker the load time.

    - Versioning - All code in an assembly must version at the same rate.

    - Security - All code in an assembly has the same identity and is granted the same level of trust.

    Assemblies and Performance

    - Prefer single, large assemblies to multiple, smaller assemblies

    - Helps reduce working set of application

    - Large assemblies are easier for NGEN to optimize (better image layout, etc)

    - If you have several assemblies that are always loaded together, combine into a single assembly.

  • Eric Gunnerson's Compendium

    C# and Aspect Oriented Programming


    One common question I've heard recently is “Are there any plans to add AOP support to C#?”

    We don't currently have any plans to add AOP into the language.

    My current thinking - and I'm not speaking for the whole design team now, though I think my position is at least somewhat representative - is that the scenarios that are mentioned around AOP don't justify the inclusion of new language features. One of my concerns is that AOP adds a whole new level of complexity to reading code, in that the code that is executed in a method isn't all in the method. The scenarios I've seen listed are around logging and monitoring.

    So, I think it's fair to say that we're in a “wait and see” attitude on this one. If there are compelling scenarios in this area, I'd like to know about them.

  • Eric Gunnerson's Compendium

    Why static import is bad...


    John Rusk asked me to elaborate on why I think static import is bad.

    It's all about readability. Most people agree that the average line of source code is read far more times than it is written, which means that being able to understand the line is more important than being able to write it quickly.

    Static import is bad because it adds an exception to the rules that everybody has to know and remember. If you see

    int x = Process(s);

    it's a line of code that's easy to understand, because you know what Process is, and more importantly, you know where to go look for it.

    But if you add the capability of doing static imports, Process() can now come from other places, so you have to keep that in the back of your mind, and may have to traipse back to find the import statement. A good IDE could help out at this, but I don't think that should be a language design point.

    One can argue that for its intended use - things like Math.Sin(), it will make things clearer, which I agree with. The problem is that I can see this feature being used by people who are familiar with their code to save time, and for them it's obvious that they've done that, but that's not true for the poor guy who inherits the code.

    Any feature that comes with the kinds of warnings that were given at the introductions yesterday is questionable in my book, and I don't like adding something that has a good potential to be abused to address a case where people are doing the wrong thing already.

    Of course, you can argue that C# has lots of areas of potential abuse, and I'd have to agree with you there, though I think the utility of those features is higher than merely saving a few keystrokes.

  • Eric Gunnerson's Compendium

    JavaOne: Day Two


    Still having problems with my wireless, after two BIOS updates and a driver update. I'm back to hardwired network in the hotel room. Thanks to all who added more information at the end of the post on yesterday.

    Today was a good day. I skipped the rather skimpy conference continental breakfast (I've really been spoiled by TechEd), got something at the hotel, and headed over for the keynote.

    Scott McNealy is a very good speaker. He comes across as folksy and funny. He spent some time talking about the Microsoft and Sun agreement, and explaining why Sun did it. It's very strange for Scott to be saying nice things about MS - I guess it's good that Larry hasn't changed.

    He talked a little about the press that Sun has been getting and their financial situation. This was primarily for the analysts and press (who got to stay the whole time today).

    Notable events:

    A game demo using Java as a script language in a first-person shooter. That's labelled as a “game using Java technology”, though I didn't think it was much of an accomplishment, as that can be said of many languages (Python, Perl, Tcl, but not - to my knowledge - about C#)

    The second was a game engine written in Java, which looked okay but a bit jerky in demo. Without knowing what kind of rendering it was doing, it's hard to know how impressed to be, but details were not forthcoming.

    The third was an unveiling of the Phantom by Infinium labs, where they said they would be shipping J2SE on the machine. Beyond that, and pulling a drape off a mockup of the machine, that was about it. It's obviously not working hardware yet, and the Java part really seems to be an “also available“ item.

    Taming the Tiger 5.0 Talk

    This was a talk that covered most of the language features not covered yesterday. The ordering of the talks was unfortunate, but I've been there at some of our conferences.

    As others noted in comments to my last post, if you use 1.5 features, you have to run on a 1.5 VM. So apparently the goal was to keep VM changes to a minimum rather than having no changes. I can understand not wanting to require all JVM writers to have to make big changes to support generics.

    There was lots of talk about foreach, and “gushing“ would not be going to far (“Once you start using foreach, it's addictive“. I agree that it's a great feature.

    I got my first introduction to the new Java enum support. They went for what I would call a “full“ implementation, in that they're class-based rather than being based on integers (my guess is that part of this is also to keep JVM changes to a minimum).

    Java enums have some “interesting“ capabilities. For example, you can write:

    public enum Operation {

                PLUS {double eval(double x, double y) {return x + y;}},

                MINUS {double eval(double x, double y) {return x - y;}},

                TIMES {double eval(double x, double y) {return x * y;}},

                DIVIDE {double eval(double x, double y) {return x / y;}},


                abstract double eval(double x, double y);



    and then write:


    for (Operation op: Operation.values())

                double results = op.eval(x, y);

    That, I submit, is a really weird thing to do, and I don't understand the utility of being able to do this as part of an enumerated type. Am I missing something here?

    Static import is a feature to allow you to write something like “Sin“ rather than “Math.Sin“. I don't think this is good for a language to do.

    More Programming Puzzlers

    A very interesting and well-presented, in which 8 programming puzzlers were presented by two presenters (alternatively). They were all console apps, and the puzzle for the audience is to figure out what the apps print. I was slightly hampered by my lack of Java library knowledge, but I got 2 of the 8.


    I’m happy to say that 3 and perhaps 4 of the puzzlers aren’t possible in C# because we have more stringent rules. A particular one that almost the entire crowd missed was the lack of break statements in the switch statement (I missed it, too).


    The format they used for this was very successful, and I think it’s a nicer way to do this sort of thing than the approach I used at my TechEd talk.


    Joshua Bloch is a very good presenter.

    Expert Panel on Agile Java Techology-based Development

    I didn't get a lot out of this. There was lots of good advice, but nothing terribly exciting.

    I have a couple of BOFs that I'm attending later. I like the BOF concept, but having meetings at 10:30 when you've been up since 6AM isn't the easiest thing, especially when you're on your second night.



  • Eric Gunnerson's Compendium

    JavaOne: Day One



    Today was the first real day of JavaOne.


    I woke up, worked out, and got to the convention center in time to play a game or two of pinball before I went to the keynote. There are a bunch of pin, air hockey, and foos tables around, and one of the pins is a Twilight Zone, widely acknowledged to be the best pin that Williams ever produced. Ive been thinking about buying one, so it was good to have a chance to see if it was as good as I remembered. And, with a few exceptions (this pin had a sticky upper flipper, a lock that didnt always work, and it was on carpet so you couldnt do slide saves), it was pretty good. Hmm. Perhaps when the motorcycle sells.


    I should state at the beginning that this is all from a Microsoft Guy perspective. Id appreciate any comments and/or corrections if you think Im off base.


    The keynote this morning was a little bit uneven. Ill give some high and low points.


    High points

    • A nice video about how the community is what it is all about
    • Open sourcing Java3D
    • Open sourcing looking glass, a 3D longhorn-ish windowing system, real soon now.
    • An air-powered t-shirt cannon, controlled through a web browser. But it would have been better if they did a rich client interface (the client is back is one of the sayings from today), and could target a specific area of the room. 

    Low points

    • Using BMWs iDrive system as an example of vibrant Java support for other kinds of devices. First of all, it took about 30 seconds for the system to boot up, and then the demo was less than inspiring. Car navigation systems arent terribly innovative right now, nor showing us an options page terribly exciting, especially when the demo delivery was totally devoid of passion. It doesnt help that IDrive has been universally panned by the automotive press as as a solution looking for a problem (not a comment on Java, just a reflection that buttons and sliders are a pretty good user interface).
    • Doing an audience applause thing to vote for the image on the new box of Java Studio Creator, but then not reporting the results.
    • A demo of a medical monitoring device that talks with a phone. Neat demo, neat concept, but the use of Java was fairly incidental.


    Weird points

    • Kicking all the press out after the first part with, okay, now its time for all the press and analysts to go to room 123. Cmon, stand up and go.


    The Sun position ends up being somewhat strange. They dont want to alienate the other sponsors at the conference, but they also want to sell their stuff, so they go from talking about how great the community is to how great their stuff is.


    Another big difference from TechEd is that most of the presentations are not done by program managers or marketing people. That has a potential to give a better connection to the real developers, but runs the risk of having presentations that are less than effective. I dont think they really succeeded in relating the things that they were doing to actual customer problems that needed to be solved.


    New release of J2SE


    I also attended a talk entitled, Fast Track to the JavaTM 2 Platform, Standard Edition (J2SETM) v5.0 (note that Sun is syncing their version numbers at 5.0) that covered some of the improvements in the new (codename Tiger) release.  The language ones will be covered in more detail in a language talk that I go to later (6:00 7:15), and then later at a BOF session starting at 10:30PM (what *are* they thinking there are more sessions scheduled at this time than at any other time).


    They claim:

    • Improvements in starting time, up to 50% on a minimal swing app. It looks like they may be doing something along the lines of ngen, but there wasnt enough detail to be sure.
    • Some new and interesting APIs for monitoring and debugging.
    • New look and feel support (I think in Swing, but I didnt write it down for sure), that can give you either XP-style, Apple style, or a new Java style named Ocean.


    This was a hard talk to watch. With all of the cool stuff that is showing up in their new release, Id expect it to be easy to get applause from the crowd, but the talk didnt elicit any from the totally packed house (easily over 1000 people).


    New Features in the JavaTM Programming Language


    Gilad Bracha, computational theologist, Sun


    Mads Torgersen, Aarhus University


    I love the title computational theologist


    This was a fairly entertaining talk, though the presenters started out by saying were tired of talking about all the new language features over and over, so were going to talk about two areas that we find interesting instead of covering everything.


    Their justification for autoboxing is similar to the justification we used when adding it to C#, though Gilad said that he had been campaigning to add it for years, but that having C# exist made it easier to make things happen.


    Java has always put types in two camps the primitive types, and objects. To bridge the gap, they have reference type wrappers, such as the Integer class, which wrap an int. This makes using lists of primitive types fairly painful.


    Where in C#, we would write something like:


    ArrayList a = new ArrayList();





    foreach (int i in a)


                int j = i;




    Even though there is boxing going on there, its largely hidden from the user, and the model is fairly simple.


    The Java equivalent is:


    Arraylist a = new Arraylist();

    a.Add(new Integer(1));

    a.Add(new Integer(4));

    a.Add(new Integer(9));


    Interator i = a.iterator();

    while (i.hasNext() )


                Integer val = (Integer) i.next();

                int j = val.intValue;



    Theyre trying to simplify this in Java 5.0, both through generics, and through the addition of autoboxing. Generics isnt enough by itself, as switching to an Arraylist<Integer> would only get rid of the cast in the call to next(), which isnt that much of an improvement. What they need is a way to make Integer and int interchangeable, which is what they do through their automatic invocation of boxing and unboxing.


    The key difference between C# boxing and Java 5.0 boxing is that C# boxes between primitive types and object, and Java does it between primitive types and the predefined wrapper types. This allows them to do implicit conversions both directions (an Integer and an int are pretty close in behavior).


    There are some issues on this that have to do with object identity. Consider the following:


    Map m = new Map<Integer, String>();

    m.add(3, foo);

    string s = m.at(3);


    What does the third line do? Well, it turns out that the two 3 values arent the same because they are autoboxed to different reference types. That behavior is a bit surprising.


    To improve the situation, theyve come up with an interesting modification, which I believe this is not part of the standard, but part of javac.


    They get around this and Im not making this up by playing tricks for small integer values, but not for large integer values. They did not give an exact description for how this behavior is controlled.


    As one attendee stated after the talk, I like the idea of autoboxing, Id just like it to be consistent.  I understand the problem that not having value type identify for the wrapper classes causes them and why theyre stuck with that, but to work around it a bit is a surprising choice, and probably a mistake.


    Wildcards in generics


    The second area the touched on is generic wildcards, which is an interesting and somewhat controversial addition to the Java 5.0 generic support.


    This is best explained through an example, though Ill warn you at the outset that this is something Ive only looked at a couple of times, so the example may not be that great.


    One of the disadvantages in some generic approaches (C# included) is that theres no way to express List<anything>.  Well, actually, there is you can write:


    List<object> c;


    But that has the side effect of only being runtime typesafe, which is normally not what you want. You can assign a List<Apple> to a list of object, but theres no compiler support to keep you from adding a Banana to that list.


    Wildcards let you get around this. You can write:


    List<?>  c;


    As a type, and any list can be assigned to that type. This is pretty close to List<Object>, so to get what you want, you would typically do something like:


    List<? extends Fruit> c;


    Which means that c can be a list of anything, as long as that anything is a Fruit or somethng derived from that. That means I can now write:


    c = new List<Bananas>();


    and I can pull items of type Fruit out of list c. What I cant do is add items to c, because I might add an Apple to the list, which is clearly wrong, and therefore prohibited by the compiler. This compiler prohibition is one of the big points of supporting wildcards.


    Wildcards can also be expressed as requiring a superclass:


    List<? super Apple> d;


    What does that mean? Well, it means that d can be a List<Apple>, or a List<Fruit>. On this list, I can safely add an Apple, because an Apple can happily exist in a List<Fruit>, but when I pull items out of the list, I can only pull them out as Object, because they aret forced to be apples.


    So what does all of this give us? The first benefit is nicer signatures. I can write:


    Void reverse(List<?> a)


    Instead of writing:


    Void reverse<T>(List<T> a)


    I dont really see this as much of an advantage, especially since the way I implement the first one is by calling a private version of the second one.


    The second advantage is that this syntax works where generic methods arent allowed in constructors, for example.


    I dont think this are worth the additional complexity, especially on a language that has prided itself on simplicity. The presenters quote was, It does the thing you expect if you expect the right thing, which I think is a different philosophy that Java has advocated in the past.


    Java 5.0 and C#


    Many people have said that C# is a Java rip-off. While C# does draw from the experience of many languages, its interesting to look at the new Java language features that are showing up in V5.0.



    C# 1.0

    C# 2.0

    Java 1.4

    Java 5.0


























    Params / varargs






    A few notes here.


    On foreach, Java doesnt add a foreach keyword, but they do support the equivalent of foreach using the for keyword. Though I was interested to note that they referred to the feature as foreach even though they dont have that keyword.


    Attributes (known as annotations in the Java space) actually have two purposes. They support a design-time only mode, where you write the annoation, and then run a tool that does code generation on top of your classes to generate the boilerplate code. In this scenario, the annotations dont end up in the metadata. And then there is another version in which the annotations do end up in the metadata.


    On the generics front, one of the important design points for the Java version was that it run on all existing JVMs (ie its 1.4 compatible). Since their JVM isnt generic-aware, they dont get any of the performance benefits of having generics. There is still no way to do an efficient generic collection over a primitive type. While I understand the constraints (ha ha) under which they did their design, I think its unfortunate that developers will still have to make the decision between the efficiency of arrays and the convenience of collections in some cases. To be fair, this is still true in very perf-sensitive scenarios even with .NET generics, but this is a far smaller number of items. Another disadvantage is their limited support for finding out about a generic type through reflection,.



  • Eric Gunnerson's Compendium

    More on AOP scenarios


    The big scenario that always comes up WRT AOP programming is logging. I agree that that whole feature space - which I'll lump into the “instrumentation” bucket - is a good scenario, though AOP is obviously not the only the way to approach it.

    What are the other scenarios? If you can give me an example in code on what you would do with this kind of support (or what people are already doing with it in the Java space), that would be helpful. It seems that the examples I'm looking at are all related to logging.

  • Eric Gunnerson's Compendium

    Life Simplification


    A good friend of mine recently resurfaced after being out of touch for about 18 months. The last time I had lunch with him, he was having some marital issues and had just joined the ranks of the unemployed (he's a tech guy as well).

    In the 18 months, he got divorced, took some Spanish classes, and then went on a home-study trip to Costa Rica. When he got back, he decided he needed a different kind of job, so he's now working as a ramp service agent for Alaska Airlines at SeaTac airport, and looking to get back into writing.

    I envy his ability to push the reset button on his life, and then figure out what he really wants to do when he grows up.

    I've been trying to simplify my life as well recently, though I doubt that any changes I make will be as drastic as his were.

    The tradeoff between money and free time is a hard one. Ideally, I'd like to have both, and while that could happen if my stock market investments go well, it's not something that's going to happen overnight - or even in the next few years.

    I may write about one specific “life simplification” decision in a separate blog, if I decide to go that way...

  • Eric Gunnerson's Compendium

    Close one chapter. Open another?


    A few days ago, I said that I was considering a big decision (for me) that would simplify my life.

    After a bit of discussion, my wife and I have decided that we're going to sell our motorcycles (though we may replace them with off-road bikes). This is a somewhat painful thing to do.

    Let me explain.

    Way back in college, I drove a 1968 Citroen Safari station wagon. Citroens have a very interesting hydraulic suspension that is unsurpassed in ride quality. They do have a few drawbacks.

    First of all, Citroen is not known for their horsepower, with the exception of the Maserati-engined SM.

    The second is that they tend to have timing chain problems when they get high mileage. The timing chain runs from the crankshaft to the camshaft, and opens and closes the valves. At least it does until it breaks, at which time the pistons come up, whack the valves, break them, and then proceed to embed the valves in the tops of the pistons. All the while making a most horrific sound.

    So, there I was in my senior year, and I need a mode of transportation, and I had $800 I could allocate to the effort. That would either buy me a pretty poor car, or a halfway decent motorcycle, so I soon had a Honda FT500, and was commutting on it.

    That led to a bit over a decade of commutting almost every day (even through some snow), riding somewhere around 80,000 miles, and teaching a fair number of classes for the Motorcycle Safety Foundation (if you're thinking of riding, make sure you start there). I upgraded bikes twice for me and twice for my wife, and we used to spend a fair amount of time riding.

    Then, we bought a house in Bellevue, and commutting by bike no longer made sense. I still rode occaisionally, but over time I've gotten more busy, and the bike hasn't been out of the garage since last October.

    It's sad. I still really, really enjoy riding - the power to weight ratio is far better than nearly all cars (at least those I could justify buying), but it's something that you need to do often to be proficient, and I just don't have time these days. Or, to put it differently, there are lots of things that rank higher right now, and we're paying for both depreciation and insurance on both bikes.

    So, I put ads for a 1997 Honda VFR750 and a rare 1994 Honda CBR400RR Japanese home market spec in the MicroNews.

  • Eric Gunnerson's Compendium

    Build Comment Web Pages


    In VS2003, there is a feature known as “Build Comment Web Pages” that was designed to take XML doc comments from your code, and create web page documentation.

    If you try to find it in VS2003, you won't have much luck, and I thought I'd explain why. We got a fair amount of customer feedback around the disadvantages of the current implementation, and that it wasn't really very useful.

    We've therefore elected to pull it from Whidbey. We are exploring whether we can provide a feature that meets our customers needs in the future, but it didn't fit into the schedule.

    Luckily, NDoc is available, and it comes much closer to what you want than Build Comment Web Pages did. You can find articles about it here and here and here and here. Oh, and here, too.

  • Eric Gunnerson's Compendium

    Risk, Filtering, and what you love.


    A good friend of mine wrote in response to my recent post:

    Every person that I have ever known that has had a motorcycle has been in an accident, and I would hate to see that happen to anyone else.

    I've had numerous people say the same thing to me over the years, and while I appreciate the sentiment, I've always found the statement a bit annoying, so I'd like to talk about that sort of statement in general (not picking on you, Nick...)

    People have a poor perception of what the true risks of an activity are, and their perception is often based on whether they participate in the activity or not.

    There's a process I like to call filtering going on here. The same people who make such comments about motorcycles don't make them about automobiles, because they understand automobiles and aren't thinking about the risks.

    It's true that motorcycles are statistically more dangerous than cars, but it's also true that there are lots of stupid and/or drunk motorcycle riders. I was rarely the first, and never the second. I've had friends who had two or three accidents in 5 years, but I didn't notice anyone telling them they should stop driving.

    Life is full of risks. I'm actually a fairly risk-averse person - I didn't take big risks when I was riding, and I don't take big risks when I'm cycling or skiing. I work on my skills to reduce my risk, but I think you have to take risks to do the things you love.

  • Eric Gunnerson's Compendium

    Uncontrollable Urge


    I can handle the “Who” music playing in the background in bars, but I'm afraid that I have to draw a line at Devo music in commercials. I just watched a Mitsubishi ad that used “Uncontrollable Urge” in it, and I think there's another one that I heard recently.

    That's just wrong on so many levels.

  • Eric Gunnerson's Compendium

    The W in Seattle


    Last night, my wife surprised me with a night at the W in downtown Seattle as a late birthday present.

    The W is currently my favorite hotel by far. I spent a little time last night thinking about why.

    It's not because they have a “living room” rather than a lounge.

    It's not because there's house (or trance (or drum and base (or something like that))) music playing in the elevators.

    It's not because the rooms have really clean design.

    It's because the experience is consistent. Somebody took the time to think about the whole hotel experience, and make it as smooth as possible. Even down the “do I want the sheets washed” sign, which is a wheel that lets you set it to whatever you want.

    I appreciate that level of thought.

    We had dinner at Cutters, a great place for seafood.

    This morning after breakfast we walked over to the new Seattle Library. Nice building, but the neon green is too jarring.




  • Eric Gunnerson's Compendium

    The Lunar Men


    The time: The early 1700s
    The place: England, at the beginning of the Industrial Revolution.

    In this book, Jenny Uglow details the lives of the group of men - industrialists, scientists, doctors, and others - who made up the “Lunar Society of Birmingham“.

    Some of them you've may have heard of - James Watt, Joseph Priestly, Erasmus Darwin. For others, such as Josiah Wedgewood, you may know the name from something else .

    And other you've probably never heard of.

    This is a pretty good book. It's interesting, for example, to find out about the amount of chemistry that is required in pottery making to get the right result.

    It would be a better book, however, if it were around 300 pages rather than 500 page in length. There's a lot of detail there, and while I appreciate a desire for historical accuracy, after 400 pages I lost interest and moved on.

  • Eric Gunnerson's Compendium

    The Difficulties of Language Design


    Phil Haack writes about the difficulties of language design.

    And no, I'm not linking just because he mentions me twice...


  • Eric Gunnerson's Compendium

    JavaOne Day Three


    JavaOne Day Three

    Last night I went to a couple of BOFs (Birds of a Feather sessions). The first one was on the new Tiger features. This was mostly Q & A and requests for new features in J2SE (the C# analog would be in the language and BCL, with a few runtime issues thrown in).

    Having an organized panel event to do this is a very interesting thing to do, and there were a bunch of people who came to listen rather than ask specific questions. It’s sort of like a cross between what we do at “Ask the experts” and our cabana sessions, but I think the fact that it’s both community driven and public makes it different from what we’ve traditionally done. We could do more in this area.

    The second BOF was on Eclipse, but I didn’t last since it was all about people writing packages for Eclipse, not users of Eclipse. I met up with Luke Hutteman (SharpReader) for a drink afterwards.

    All the Platinum sponsors get their own keynotes, and I decided to skip the Nokia one this morning. There is a lot of Java stuff in the mobile space, but I think that this will remain a niche market for a fair amount of time. Some companies will make good money here, but it doesn’t have the opportunity you’d find in the web or rich client (or even PDA) area. The number of downloaded ring tones has been mentioned a couple of times at the conference, but I don’t think there is a strong connection between that and downloadable software. Yet.

    What’s new with NetBeans IDE

    Steve Wilson, engineering director, netbeans

    3.7 million downloads since June 2000
    70,000 on the mailing list

    Interestingly, from a show of hands, many people use the IDE, but very few (<5%) use it to build rich clients.

    The talk was very much a feature dump, so it wasn’t terribly informative. They did start with a release roadmap:

    3.5.1 August 2003
    3.6: April 2004
    4.0: Q3 2004
    4.1: Q4 2004

    Features they talked about:

    • New look and feel (not using “metal”)
    • Code folding (aka regions in VS)
    • Auto-hide windows (as seen in VS)
    • Automatic refactoring. Their approach seems very similar to ours – they are using the javac compiler to get their program information, and they support a similar set of refactorings (rename, extract method, etc.). They also do preview. It wasn’t clear whether they do cross-project renames
    • Ant-based project system (they had no real project system in the past)

    The big thing that they demoed (after a few demo problems) was integrated support for JFluid. This is a technology that allows for dynamic bytecode injection into an already running code, and they’re using it for application profiling.

    The demo is fairly impressive. Not only do you get CPU and memory profiling as you run your application, you can walk up to an already running application, do some profiling on it, and then leave it the way that you found it.

    I know that we have some profiling support in VS Team System, but I don’t know the details, so I won’t attempt to make a comparison.

    Java Studio Creator Model and Architecture talk

    The Java Studio Creator product is Sun’s value-add on top of Netbeans. I didn’t know enough about how beans work for this talk to be of much use.

    Aspect-Oriented Programming: Great new thing or great leap backwards?

    • Gregor Kiczales
    • Graham hamilton from Sun
    • Cedric bust – BEA
    • James Gosling

    This was an interesting panel discussion. Gregor spent a few (8) minutes on a discussion of the “what and why” of AOP.

    Some of the area of application mentioned were:
    • Design patterns
    • Swith thread safety
    • Policy enforcement (authenticaitno, synchronization, architecture)
    • Transaction

    There was common agreement that there current weren’t a set of “right rules” for safe AOP.

    I found a lot to like in Gosling’s position, which I’ll paraphrase (probably poorly):

    Gosling – you can always find ways where it’s easier to slice it one way or to slice it the other way, in nouns or verbs, and as systems evolve, you end up with a quadratic explosion in code complexity.

    The point here is that O-O cuts the system one way – in terms objects and methods – and AOP cuts the system in another way. Some things are easier in O-O, and others are easier in AOP. But when you put them together, you have to deal with the complexity of both approaches.

    There was some discussion about when/whether AOP will get to a final state, where it seems obvious what to do. Gosling likened the current situation to a food fight, and noted that there is still food in the air.

  • Eric Gunnerson's Compendium

    Nullable type support in the community preview


    One reader commented that nullable types don't seem to fully work in the community preview drop.

    He's correct, and I apologize for not making that clearer in my post.

    The time constraints of the community preview prevented us from getting all the nullable support in the compiler, but it will be there in the upcoming beta.

    For the community preview, the following things work:

    • You can write a nullable type using the “?“ syntax
    • There are conversions from T to T?
    • You can use HasValue and Value on the type.

    The following things don't work:

    • Adding two nullable ints together (or any other operations that operate on the underlying type)
    • Comparing a nullable instance to the literal “null“
    • Using the ?? operator
    • Converting from S? to T? if a conversion from S to T exists.
  • Eric Gunnerson's Compendium

    Off to JavaOne


    Sunday I'm flying out to San Francisco to attend JavaOne. I haven't been to a competitor conference before, and I think it's going to be an interesting experience. I'm very intersted, for example, to see what the message is around the new “Tiger” features.

    If you're going to be there and would like to hook up, drop me an email.

    Oh, and if you have any tips for getting the most out of my time, let me know.


  • Eric Gunnerson's Compendium





    1. 100 years
    2. An elaborate ritual practiced by a secretive cult, in which members devote themselves to extended periods of self-flagellation on their elaborate instruments. The group has an elaborate caste system, where members advance by demonstrating their ability to absorb punishment on a daily basis and their willingness to devote time and money to their obsession.
    3. The subjective amount of time that it takes to ride a bicycle 100 miles.

    I was feeling good. After a short lunch break (3:28, 56 miles), I had hooked up with a few riders and made good time from Monroe back towards the mid-point food stop. On the way I decided to make a pit stop at one of the rest stops. Clipped out of my left pedal, pulled into the gravel, stopped.  Went to clip out of my right pedal, overbalanced, fell over into the gravel. Unclipped, laughed, and thanked the other riders who came over to see if I was all right.


    So, I was a little more tired than I thought. But I'm getting ahead of myself now.


    Late last summer, my wife and daughter and I rode in the Headwaters Century, put on by the Tacoma Wheelman’s club. I did the 66 mile route, while my wife pulled my daughter on her trailercycle for 45 miles (a bigger accomplishment than what I did, actually).


    I had a lot of fun on that ride, and decided to set my sights higher. The traditional progression for riders in the Seattle area is to do some sort of century, then do the Seattle to Portland (STP) ride in two days, one of the biggest organized rides in the country (they may sell out at 8000 riders this year). Then, if you want a much harder challenge, you can do STP in one day, or RAMROD (154 miles, around 8500 feet of elevation gain), or even the RAPSody (150 miles, 9400 feet of gain). Or, if you're more serious, you could do a 1000 KM Brevet (though to be fair, that's over 3 days).


    After consulting with a few experienced experts, I decided to make my goal for this year to ride RSVP (Ride Seattle to Vancouver and Party), a two-day ride from Seattle to Vancouver BC. This ride got started the year that Mount St. Helens erupted, and STP couldn’t be held.  It’s much smaller than STP (900 riders max), and purported to be much prettier. It’s also a bit shorter, at 183 miles to STPs 200 miles.


    To ride that distance, I needed an intermediate goal, so I chose the “Flying Wheels Summer Century”(“Screaming Thighs” is perhaps a better name), one of the toughest centuries in this area, because of the hills.  I’ve been pre-riding parts of the course for a few weeks now, and was pretty confident that I could finish the ride.



    The ride itself was great. The one section that I hadn’t ridden turned out to hillier than I expected, but all else was what I expected. Pre-riding it was a very good thing to do.


    I rode most of the first two thirds of the ride by myself. I hooked up with groups for a while, but their pace was just a bit too high for me to be comfortable. After the 66 mile stop, I hooked up with a guy who was riding the same speed, and we rode the rest of the ride together (misery loves company). That makes the ride much more enjoyable, and you have the opportunity to draft on each other, which gets you any where from 10% to 30% less effort.


    A few statistics:


    Slowest speed: 6.5 MPH, riding up the first big hill (12% grade).

    Fastest speed: 43 MPH, screaming down a hill at 90 miles into the ride. I got passed

    Calories Expended:  3000-4000

    Water: Around a gallon


                24 ounces of gatorade

                8 fig newtons

                2 Balance Gold bars (Chocolate Mint, yum yum)

                1 banana

                1 package beef jerky (about a gram of sodium, very important)

                2 Carb-boom gel packs (Apple Cinnamon). Pure glucose gel

                ½ bagel

                4 bunches of grapes

                2 handfulls of pretzels

    Distance: 101.75 miles

    Time: 6:49:22

    Average Speed: 14.9 MPH

    Elevation Gain: 2900 feet



    My goal was to finish 100 miles in less than 7 hours, which requires an average of 14.3 MPH, and I’m very happy to have finished earlier than that. Though I could have ridden more, I definitely didn’t want to ride any more at that point.


  • Eric Gunnerson's Compendium



    A while back, Gus wrote about his ultimate devotion to Avril.

    Well, that's not exactly how he put it, but I'm sure that's what he's meant.

    I put off writing about it for a while, since I thought it would be good to milk his embarassment for a while. I, of course, have the excuse of having a 10 year old daughter, and therefore any listening that I might do to any songs by Avril is merely a way for me to relate to her world. Thankfully, Samantha is no longer interested in Britney, which I am thankful for, both for Britney's image and her her vocal abilities. Or the lack thereof.

    So, Avril recently released a new album titled, “Under My Skin“. I got big daddy points by doing a pre-order on Amazon. Having thought her original album was pretty good, I was wondering what this one would be. The sophomore album tends to be one of the worst that an artist  puts out. All the good stuff has been used up on the debut album but the artist hasn’t yet hit her songwriting stride, plus the record companies want that second album now. “Van Halen II“ is a primary example. Any band that wrote “I live my life like there's no tommorrow. All I've got, I've had to steal. Least I don't need to beg or borrow. Yes, I'm living at the pace that kills“ should be pretty embarassed to them write “Barely a beginner, but just watch that lady go. She's on fire, 'cause dancing gets her higher than anything else she knows.“, especially to a poorly-disguised disco beat. On the other hand, a quick look at Amazon shows that Van Halen II gets 4.5 stars, the exact same rating as their first album, which shows that the public has no taste.

    I will admit to being somewhat of a non-purist for music. I like stuff that sounds good and is hard to sing, and while I don't like over-processed vocals, I do prefer a note that has been pitch corrected to one that is out of tune. There's no doubt that some of the songs on this album have some vocal processing, but it's been applied fairly lightly, and I appreciate that Avril is both overdubbing her vocals and singing with different timbre.

    The reviews of Under My Skin have mostly focused on the somewhat simplistic lyrics, but the number of groups who can write both great music and great lyrics is pretty small, so I think that that’s not a big issue.

    The album is pretty good overall, and you can listen to it more than once. There are two songs of note:

    “Don’t tell me” starts out as a very typical teenage love song, but then makes a transition into a nice rocking song.

    “He Wasn’t” seemed very familiar to me, and when I listened carefully, I realized that there is a fair amount of Green Day influence there. Which is a “good thing”.

    So, to answer Gus' question, since his Avril devotion is based upon musical qualities, I think he's on safe ground.

    He should, however, be embarassed about his obsession on Mary Kate and Ashley. I mean, dude, we're tired of having to look at the autographed magazine cover over and over.

  • Eric Gunnerson's Compendium

    JavaOne blogger Meetup

    I'm planning on going to the JavaOne Blogger Meetup on Monday night. It should be an interesting event.
  • Eric Gunnerson's Compendium

    Laptop wireless issues


    I've been having problems with my wireless here - the same problem I had at TechEd.

    I'll connect to wireless just fine, and then after about 30 seconds, my system process will suddenly start using 100% of the CPU, and the whole system will hang. Turn off the wireless, and everything works fine.

    Any ideas? The laptop is a Compaq Evo N600c running XP Pro.

  • Eric Gunnerson's Compendium

    JavaOne: Day 0


    I flew down from Seattle this morning to attend JavaOne. I'm currently in a lounge, where the wireless is working fine (though I expect the load tommorrow may kill it, as it did at some parts of TechEd).

    It's very strange to be at a Sun conference. A few random thoughts:

    1. The Java colors are a lot cooler than the Visual Studio ones.
    2. Being able to pick up your badge through a barcode reader in your hotel is cool.
    3. Not having a quick reference guide or a decent map is a big disadvantage.
    4. Most of us know what a “Hackers Lounge“ is for, but I'm not sure that all the press will have the same understanding.

    I'll be writing more tommorrow.

  • Eric Gunnerson's Compendium

    C# chat for today cancelled


    Due to unforseen technical difficulties, the chat for today has been cancelled.

    I apologize for the late notice on this, and I apologize more for anybody who showed up to chat and couldn't. We will work to reschedule.

  • Page 1 of 2 (38 items) 12