Monthly Archives: April 2004

Lordy, lordy, BASIC’s forty!

I had nearly forgotten that we’re approaching a major milestone this weekend – the 40th anniversary of the first BASIC program! Happy birthday, BASIC!

I only remembered the occasion because the AP Newswire did a story on the anniversary and they wanted to get a quote from someone at Microsoft about BASIC. They wanted Bill Gates, but they got me – too bad for them! Anyway, I had a very pleasant chat with the reporter about BASIC and Microsoft and such. Although I see where he’s coming from with the idea that BASIC is no longer with us – certainly not in the original, 1964 version, at least – I still like to think that the spirit of BASIC lives on strong in Visual Basic and all the other BASIC inheritors out there…

Thanks, John Kemeny and Thomas Kurtz!

The digital divide (Or, “right clicking is hard”)…

In my previous entry on the relative uselessness of the status bar, I got a bit of flack in the comments from people who find the status bar extremely useful. In fact, I’m one of those people – I regularly use the status bar of IE to figure out the URL of a link that I’m hovering over. And I use the handy status bar functions (like Count, Sum, etc) in Excel all the time. But the point is that you and I are not typical. I don’t think it’s bad at all to put stuff in the status bar for advanced users – it’s just bad (as people are wont to do) to put stuff in the status bar that the average user really might want to know. There’s a big difference between the advanced users and average users sometimes.

Which reminds me of another funny story from my Access days. A favorite place for developers to stick important things in applications is right click menus. “Hmmm, we don’t want to clutter the menus up with this, why don’t we put it on a right click menu?” During the Access 2.0 cycle, one of our PMs (who shall remain nameless) started having this weird problem. Every once in a while, she would be using Access 2.0 and her forms would just stop responding. They wouldn’t hang, per se, they would just not accept any more mouse clicks or keyboard presses. The poor developer who owned the forms engine, Peter, couldn’t figure out what was wrong. He looked extensively at the code to see if he could suss out what the problem might be, but no luck. I believe he even tried instrumenting the PM’s version of Access to see if he could isolate the problem. Finally, one day he was sitting in her office watching her work when it happened, and he just happened to figure out the problem. You see, the PM had a very slight hand coordination problem – when she went to right click the mouse, she would occasionally have an involuntary movement of the adjacent fingers that would cause the left mouse button to be pressed at the same time. And when a left click and a right click message came in together at just the right time, the form would freeze up. (Access wasn’t the only Microsoft product to have this problem.) Peter tracked down the problem and fixed it.

The amusing postscript to this story is that another developer on Access, Cameron (not Beccario), heard about this and thought it would be funny to play a trick on the poor PM. So he wrote a little Access macro that would put up some funny message box every time she pressed both mouse buttons together. He installed it on her computer over the weekend and figured she’d find it sometime later that week. When he got into his office late Monday morning, he had a couple of irate voice mail messages from the PM saying “what the hell did you do to my computer?” Apparently, this finger twitch was not that uncommon…

Anyway, the moral of the story, such as it is, is that things us advanced users take for granted can often pose problems for the regular users….

Status bar == almost entirely superfluous

Raymond has a short musing about why it’s not a good idea to just punt on difficult questions and ask the user. Makes me think of the good old days on Access – I seem to remember one usability person saying that some non-trivial percentage of users always reacted to dialog boxes by immediately hitting Return, thus chosing the default option. As a programmer writing UI at the time, I found that fact extremely frightening given the number of dialog boxes I had authored.

But what this really makes me think of is a usability test they did on Access one day to see how effective text placed in the status bar was. The test went like this: the user was given some task to do in Access. Unbeknownst to them, we’d stuck a message in the status bar that read “If you notice this message and tell the usability lead, we will give you $15.” Want to guess how many people got the $15? Zero. After that, we were careful not to put any important information down in the status bar, because it was 100% likely that no one would ever see it.

Instead, the status bar is just a nice little waste of screen real estate where we can put cute, innocuous little messages like “Done” (Internet Exporer at the moment) or “Ready” (Visual Studio at the moment).

The My namespace and C#

Don and Robert ask in comments to my previous entry, “Will C# be able to use the My namespace?” The answer is: yes and no.

Most of the functionality contained in My is implemented by types that will be defined in Microsoft.VisualBasic.DLL. So C# users are welcome to reference the DLL and use types such as System.IO.FileSystem or Microsoft.VisualBasic.MyServices.MyComputer. Besides the cognitive dissonance of having to actually use the name “VisualBasic,” there’s really no difficulty there.

However, the top level “glue” that brings all the My pieces together is something that’s compiler-specific and so C# users won’t see it. The top-level My stuff is compiler-specific for two reasons:

  • The My types exposed in a particular project are dependent on the type of the project. A web service project will have a different My namespace than a WinForms project will. Thus, the top-level definition of My has to be integrated into the actual building of the project.
  • Pieces of the My namespace (such as My.Forms) are dependent on objects that are actually a part of the project itself. Thus, the compiler has to specially generate those pieces of the My namespace at compile time.

Roy raises the question as to whether divergence between the languages like this is a good thing or a bad thing. While I’m sympathetic to his point about increased difficulties moving between two languages, it does raise the question: what’s the point of having two separate languages if they have exactly the same set of features? Case insensitivity vs. case sensitvity, for example, is not reason enough alone for Microsoft to invest all the money that it does building both products.

Ultimately, feature set comparability has to be a balancing act between innovation and knowledge portability. If C# and VB cannot implement a new feature without the other language implementing it, the user ultimately suffers by way of reduced language innovation. It would be hard to argue that VB users should not get Edit and Continue back because C# doesn’t plan to support it in Whidbey. Similarly, should C# users not get anonymous methods because VB doesn’t plan to support them in Whidbey? Inevitably, the best ideas of one language will be cribbed by the other language. If My turns out to be a smashing success, I’d expect C# to come sniffing ’round it the next time around. Certainly we’re watching how iterators and anonymous methods play out as we think about features for the future.

Innovation, however, does come at a cost and that can’t be ignored. But I think, in the end, the cost is worth it to both languages’ users.

Static locals are cool

Or so says a sticky note that I stuck on my monitor on Friday to remind me to blog about them. Static locals are local variables whose values are preserved across calls to a method. For example, the following method will print the sequence 0, 1, 2, 3, 4, 5, 6, etc. on successive calls:

Sub PrintNextNumber()
    Static x As Integer = 0

    Console.WriteLine(x)
    x += 1
End Sub

What basically happens with static locals is that we create a hidden field in the containing class to store the value across calls to the method. Thus, static locals are really most useful when you have a type-level value that you need to store that you want only scoped to a particular method. I thought to blog about this because I was working on finalizing my managed VB parser sample and I needed to have a lookup table for type characters when scanning type characters. I could have written it as:

Class Scanner
    Private _TypeCharacterTable As Hashtable
    Private ReadOnly Property TypeCharacterTable As HashTable
        Get
            If _TypeCharacterTable Is Nothing Then
                … initialize table …
            End If

            Return _TypeCharacterTable
        End Get
    End Property

    Private Function IsTypeCharacter(ByVal c As Char) As TypeCharacter
        Return _TypeCharacterTable(c)
    End Function
End Class

But with static locals, you can be more compact:

Class Scanner
    Private Function IsTypeCharacter(ByVal c As Char) As TypeCharacter
        Static TypeCharacterTable As Hashtable

        If _TypeCharacterTable Is Nothing Then
            … initialize table …
        End If

        Return TypeCharacterTable(c)
    End Function
End Class

One thing my code above doesn’t do is consider multi-threaded situations. We’ll automatically generate thread-safe code for static local initializers, but since I have to do extra initialization above, I should really synchronize the initialization. One other thing to keep in mind is that static locals are only preserved per-instance in instance methods. Calling PrintNextNumber on two different instances of the containing type will not give sequential numbers. If the containing method is shared, however, the calling instance doesn’t matter.

Random factoid #1: Static locals are a major reason why we used the term “Shared” for shared members instead of “Static.” We also felt that “Shared” is a lot more descriptive than “Static,” and I wonder whether C# would have chosen that term if they hadn’t been stuck with the legacy of C, but… This is probably the most painful keyword divergence between the two languages in terms of documentation.

Random factoid #2: Implementing static locals in the compiler was a gigantic pain in the ass, and we had a lot of arguments about whether they were worth the effort. There are times that I haven’t been entirely convinced about it, but I think my thoughts on this are changing…