home & news
DSL DevCon
interviews
tools
the spout
writing
fun
colophon
contact
off topic

Google

 

Spout Archive

2001-2004


It's The Thoughts That Count...

Thursday, November 4th, 2004

On an internal mailing list the other day, there was a question asking for how to make a tray notification icon come back up on the try after explorer.exe died and came back to life. Good notification icons do this and the asker wanted to know how to do it for Windows Forms. I had had a dearth of technical work at the time, so decided to dig into the problem and see if I could answer it.

I started with a dim memory of a piece in MSJ by Paul Dilascia on the subject. Searching on msdn.com, I found Paul DiLascia's 2/99 MSJ C++ Q&A (http://www.microsoft.com/msj/0299/c/c0299.aspx) (emphasis added by me):

"�provided you have Windows 98 or the Microsoft Internet Explorer 4.0 desktop installed. Whenever Internet Explorer 4.0 starts the taskbar, it broadcasts a registered message TaskbarCreated to all top-level parent windows. This is your cue to recreate the icons. If you're using MFC, all you have to do is define a global variable to hold the registered message and implement an ON_REGISTERED_MESSAGE handler for it."

From there, I dug through the SDK docs on ON_REGISTERED_MESSAGE (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_on_registered_message.asp) and found:

// example for ON_REGISTERED_MESSAGE
const UINT wm_Find = RegisterWindowMessage( FINDMSGSTRING )

BEGIN_MESSAGE_MAP( CMyWnd, CMyParentWndClass )
//{{AFX_MSG_MAP( CMyWnd )
  ON_REGISTERED_MESSAGE( wm_Find, OnFind )
// ... Possibly more entries to handle additional messages
//}}AFX_MSG_MAP
END_MESSAGE_MAP( )

Figuring I'd have to be able to call RegisterWindowsMessage from managed code, I surfed to pinvoke.net and found RegisterWindowMessage (http://pinvoke.net/default.aspx/user32.RegisterWindowMessage):

[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);

Now that I knew how to figure out the Window message value for which to watch, I looked back into the MSDN documentation on System.Windows.Forms.Control, the base class of Form and all other HWND-based classes in Windows Forms (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclasswndproctopic.asp) and the WndProc method I would have to override to catch the message, finding:

protected virtual void WndProc(
ref Message m
);

and:

"All messages are sent to the WndProc method after getting filtered through the PreProcessMessage method.

"The WndProc method corresponds exactly to the Windows WindowProc function. For more information about processing Windows messages, see the WindowProc function documentation in the Windows Platform SDK reference located in the MSDN Library.

"Notes to Inheritors: Inheriting controls should call the base class's WndProc method to process any messages that they do not handle."

Putting this together, I figured you could add "re-awakening" to notification icons in the following way (some compiler errors left in to keep readers on their toes : ):

using System.Windows.Forms;
using System.Runtime.InteropServices;

class MyMainForm : Form {
  [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
  static extern uint RegisterWindowMessage(string lpString);

  static uint taskbarCreatedMessage = RegisterWindowMessage("TaskbarCreated");

  protected override void WndProc(ref Message m) {
    if( (uint)m.Msg == taskbarCreatedMessage ) {
      // re-show your notify icon
    }
    base.WndProc(ref m);
  }
  �
}

After posting this answer to the list, I couldn't help but crank up a quick app to test it (after fixing the compiler errors of course : ). To my satisfaction, it worked immediately. I put up a notify icon in Windows Forms, killed explorer.exe and was pleased to see my icon show back up again when explorer.exe was restarted.

However, just to make sure, I commented out my code to see my icon not be restored. Those of you familiar with the internals of Windows Forms know what happened next, of course, because my notify icon was restored properly to the tray even without my code, as illustrated by Reflector against the .NET 1.1 Windows Forms implementation:

public sealed class NotifyIcon : Component {
  ...
  static NotifyIcon() {
     NotifyIcon.WM_TASKBARCREATED =
      SafeNativeMethods.RegisterWindowMessage("TaskbarCreated");
  }

  private void WmTaskbarCreated(ref Message m) {
    this.added = false;
    this.UpdateIcon(this.visible);
  }

  private void WndProc(ref Message msg) {
    ...
    if (msg.Msg == NotifyIcon.WM_TASKBARCREATED) {
      this.WmTaskbarCreated(ref msg);
    }
    ...
  }
  ...
  private static int WM_TASKBARCREATED;
  ...
}

What? Why would someone post a question about how to make something work that already worked? I figured that the questioner was referring to .NET 1.0 and I was digging through .NET 1.1 code.

However, reading through the 1.0 code showed the same support, meaning that neither the questioner nor I had bothered to check for this support before running off to add it. So, the lesson? Write your tests first!

Still, I learned a bit along the way and that was fun. : )

Discuss

The Importance of Reputation

Thursday, November 4th, 2004

My youngest son was called into the office today for pantsing a kid on the school playground. That is not at all like my son (he's the sweetest kid you'd ever want to meet), but the principal was new, so she was talking about suspension. Luckily, the secretaries knew my boy, so they were able to point out the inconsistency of that behavior with the reputation he had built in 4 years at the school. It turns out that the pantsed boy was cutting in line in front of my son, who didn't like it, so pushed him right back out of line again. The "cutter" took a swing, my boy swung back and in the process (they're only 9) they both fell. My son reached out to grab the boy's shirt to catch himself, not knowing that the other boy was also falling and got the pants instead, causing the aforementioned "pantsing."

The moral of this story is an old saying I heard when I was a kid and have lived by since: "If you rise at dawn, you can sleep 'til noon." In other words, if you build yourself a reputation for good things, when occasionally you stray, folks will cut you some slack. The converse of this rule is that if build yourself a reputation for bad things, that could well stick with you for a long, long time..

Discuss

Every Story I've Ever Written

Thursday, October 7th, 2004

I was working with a potential author on an article he'd like to write covering some ground I left uncovered in my original No-Touch Deployment piece for MSDN Mag. Anyway, he sent me the list of topics and then said the following:

"There is a fair amount of material here it might benefit from being broken into chunks. I think I will write about small chunks at a time and then we see how much belongs in one article. Rereading your original article it struck me that you had [a] story that held it together, I need to find one for me."

I've heard this kind of thing before, i.e. people ask how I turn a seemingly random set of topics into "a story." I'm all for that, but it's not really such a chore. In fact, here's the essence of every technical piece I've ever written:

"So, I want to build this thing that needs to do this, that and the other. I started with this, did it this way and it worked. Now I need to do that. Oops. That didn't work the way I thought it should. Here's what I need to do to work around the problem. OK, now I want to do the other... [repeat]"

The secret is really building up from what the reader already knows with some minimal new, interesting thing and keep on like that 'til you've covered the ground you want to cover, stringing things together with transitions that give the reader the impression of one contiguous story. If you really want to get fancy, put a personal anecdote at the front that you use as an analogy, bring it up a few times during the piece and then wrap up with something clever that ties the your anecdote together with the ground you've covered by extending the analogy in a humorous way (but that's optional).

Discuss

Settings, Collections and VS05b1 (oh my)

Thursday, October 7th, 2004

I sat down to write a new Windows Forms application in .NET 1.1 the other day, but the Visual Studio 2005 beta 1 called to me with its "menu strips" and its "user settings" and most especially its "generics," and I just couldn't resist.

To start with, it was such a pleasure to add a menu strip, add in the standard menu items (including graphics), then just strip it down to just the menu items I wanted. Then, as I added new menu items, the menu item object names were set for me based on the menu item text, e.g. startRetrievalToolStripMenuItem instead of menuItem1, which was fabulous. Not everything was wonderful, e.g. I couldn't drag and drop menu items or use Alt+arrows to rearrange them , but overall the new menu control was a pleasant experience.

Even more pleasant was the app/user settings model. To add a setting to my application, all I had to do was bring up the properties of my project, add a named setting of whatever type I wanted (more on this later) and choose whether it should be an Application setting or a User setting. Both kinds of settings are loaded automatically when the app starts and all I had to do to save them was call Properties.Settings.Value.Save() when my main form shut down. Then, with the settings in place, e.g. MyUserSetting, I could get to it after the app started from anyone in my app with a type-safe access, e.g. Properties.Settings.Value.MyUserSetting.

And this didn't just work for built-in simple strings and ints and such like. Oh, no. I was allowed to add custom and collection types like System.Collections.Generic.List<MyNamespace.MyType> as well. Plus, using generics, the underlying XML serialization mechanism worked great, because all of the types are known at compile-time (settings are stored in standard XML .config files @ c:\documents and settings\<user name>\Local Settings\Application Data\<company name>\<product name_hash>\<product version>\user.config). Being able to declaratively set app and user settings of any type and then just use them in a type-safe manner, saving them with one line of code, loading them with zero lines of code and not having to flatten my collections into comma-separated lists made things so pleasant until I hit the ugly realities of beta software, especially as new features interact with existing features and each other.

For example, because the default AssemblyVersion attribute is set to "1.0.*" in AssemblyInfo.cs (which has moved to below the Properties folder of your VS05 project), every time I compiled, all of my settings were lost. That seems very counterintuitive to me. Why should a user lose all of their settings with the new version of the application? To work around this, I changed my AssemblyVersion attribute to a hard-coded string that I now have to remember to change manually, blowing the benefit of having a version number that changes automatically with each build.

As another example, like C++ "const" of old, generics infect your code; use them in one place and you find yourself using them all over. That was fine with me (the generic Predicate<T> for finding things in a List<T> was so handy!) except that as of b1, the Windows Forms Designer gets all unhappy when you use generics. I have every hope that this will be fixed by b2, but as of right now, if I wanted to use the Designer (and it's so sweet, how could I not want to use it?!?), I had to strip out any methods or properties in my visual code that exposed generics (although method and property implementations with generics works just fine).

Stripping out List<T> brought me to the use of ArrayList instead. That worked just fine (System.Collections.ArrayList is even available via the Browse button when setting up app/user settings) until the XML serializer couldn't serialize instances of the custom type that I was using to populate my ArrayList. The error looked like this:

Could not use Xml serialization for setting: SelectedExchanges. --->
System.InvalidOperationException: There was an error generating the XML document. --->
System.InvalidOperationException: The type MyNamespace.MyType was not expected.
Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

When I start up the debugger to see the line of code where the error is happening, I ended up in Main because the code is part of the Application start-up for which there is no source code, making this even more difficult to debug. The problem was that the underlying serialization engine didn't know what to do with this custom type. The clue was the mention of the XmlInclude attribute, which you can use to tell the serializer what types may be in the ArrayList, but you have to have somewhere to hang the attributes. In this case, that lead to a custom ArrayList type for the express purpose of informing the serializer (making me really miss the use of generics, where all of the types were specified at compile-type for me automatically):

[System.Xml.Serialization.XmlInclude(typeof(MyNamespace.MyType))]
public class MyList : System.Collections.ArrayList {
  public override object Clone() {
    MyList newList = new MyList();
    newList.AddRange(this);
    return newList;
  }
}

Notice also the Clone method. I added this later because the base ArrayList Clone method creates an instance of ArrayList, not my custom MyList type. Of course, since this was all run-time type errors, I couldn't let the compiler tell me about these problems; I had to run my app and find them. Very frustrating, especially when generics makes these problems all go away.

Still, I'm very much enjoying the new productivity features in VS05 and Windows Forms 2.0 and when they work better together, I'll be even more happy.

Discuss

The Week Before Burning Man

Monday, September 6th, 2004

I was just listing my activities for the week before Burning Man and amazed even myself:

  • Shopping for and celebrating my wife's 36th birthday

  • Helping to prepare for and then watching Sells brother #1 test for his Jr. Brown belt in karate (he was amazing)

  • Hosting my aunt and grandmother on a very rare 4-day trip

  • A day-trip to the beach

  • Celebrating the birthday of Sells brother #2

  • Coordinating the update, from my house and at the last possible moment, of more than 100 pages on microsoft.com to reflect the recent announcement of WinFX being made available on down-level versions of Windows (this included 3 all-nighters)

  • Preparing for and running a 2-day garage sale of the stuff I pulled out of my house over the last 8 months in my own personal episode of Clean Sweep

  • Packing for 5 days in the desert (I worried about survival and my wife worried about having enough costumes...)

Of course, after that I spent a week at Burning Man, and today we're cleaning the playa out of everything, preparing the boys for school, hanging out with the relatives for Labor Day and celebrating our 13th wedding anniversary. Starting tomorrow, I have to figure out what to do with the Longhorn Developer Center now that WinFX will be available on down-level windows, co-author two Avalon books and one Windows Forms book and run the Applied XML Developer's Conference 5. Should be fun. : )

Discuss

What Makes A Book Successful?

Tuesday, July 27th, 2004

I got an email today from a friend who wanted to know what he could do to make the book he had in his head successful. I've thought a lot about this topic in the genre of Windows programming (I don't have a clue how to make your bodice ripper successful), but had never verbalized it 'til now, so I thought I'd run it up the flag pole and see who burns it.

DISCLAIMER: I make no claim about whether following these guidelines will make your book successful. These are just things that I think about when I'm trying to make my own books successful.

  1. Write a quality book. I know this one goes without saying, but given the state of most books that make their way to the shelves, I thought I'd say it anyway. Karen Gettman, my editor at Addison-Wesley, says it like this, "Be the first or be the best." I've never yet had any luck being first, so I really try to be "the" book in any given category. For example, I think the 6 guys who read the TAPI book would agree that I really nailed it. : )

    For me, the crux of quality (besides being able to string sentences into paragraphs and chapters in pleasant ways) is writing a book that describes how to do your work with the technology instead of that describes how the technology works. The difference is subtle, but it's what separates, for example, a book that describes how to build real applications in WinForms using the appropriate tools from a book on the WinForms classes, methods and events. Likewise, the former fills in the gaps when a technology falls short whereas the latter is frustratingly silent on such topics.
     

  2. Have a significant audience. This is the one that's killed me time and again. The Win95 user book was killed by Internet encyclopedias. The TAPI book was killed by the lack of PC/Telephony adoption. The ATL book was pretty well-received, but the audience was still not the audience size that you'd like (although it still sells nicely and we're planning on having a 2e in time for Visual Studio 2005 and ATL 8).

    Having a significant audience was the thing that killed my friend's book dreams when he called. Before our call, he was all excited about his technology (passion is an important part of the writing process and it's the only thing that can get you through the murderous back-end of a quality book [on the other hand, I understand that people that write crappy books don't have this problem, so there's something to be said for that...]). After our call, he had to admit that the market just wasn't there for anyone to purchase his labor of love once he'd produced it.
     

  3. Own the marketing. The truth is that even though publishers have full-time marketing folks, you are much more likely to know where your audience hangs out and how to reach them then they are. Plus, there are all kinds of "guerrilla marketing" things that you are much more able to do than any publishing company. For example, these are some of the things that I like to do:
     

    • Answer questions online in your area of expertise. I'm continually surprised by the number of authors that don't participate in the communities that support their technology. If you answer questions and then point folks to your book for more details enough times, folks will grow to appreciate your book without ever having picked it up (although don't just point folks at your book without answering their question -- that'll just make you look like an asshole).
       

    • Ask for Amazon reviews of your book. People often feel the need to say something nice about my book before asking me a related question. In that case, I always take the opportunity to ask them to post a review and give them the URL to do so (the difference between finding my book on Amazon and just clicking an URL can make all the difference between whether they do it or not). I never ask them to post a "nice review," btw. I just encourage them to write what they feel.

      Why do I care about them posting their reviews? According to legend, the number of reviews a book has is a fair indicator of how well it sells, regardless of whether those reviews are good or not. I don't know if it's causal, but since I can only influence one of the variables, that's what I do. Plus, the reviews look good to your family and friends when they pull up your books and since you're not going to make any money writing a book, you might as well get something out of it. : )

      Why so I want the reviews on Amazon instead of blogs, newsgroups or BookPool? Because everyone goes to Amazon to buy books and that's where I want them to see the reviews. In fact, if I see a review somewhere else besides Amazon, I'll ask the reviewer to copy and paste it on Amazon so that all of the reviews are in that one, critical place (providing them the URL, of course, to make it nice and easy for them : ).
       

    • Continue writing in your area of expertise. There's no better free advertisement for your book than that tiny bio at the end of an article that says "P. Grammer is the author of Essential EDI Programming in a Nutshell in 21 Days for Dummies." Of course, that pre-supposes that the article is good enough for folks to want to read more of your work, but if it isn't, you've got bigger fish to fry.
       

    • Bang on your publisher. Your publisher has a PR department and a marketing department. Talk to them. Ask them what they're doing for your book. Watch where they go and make sure your book is represented. Watch where they don't go and tell them to go there. Make sure your publisher signs you up to revise your book as the technology evolves.
       

  4. Pick your publisher wisely. Speaking of publishers, make sure you choose one you're going to like. It's easy to fall into the money trap, especially since every publisher on the planet can provide numbers about how they're the #1 publisher in some way for your book and you'd be a fool to go anywhere else. Unfortunately, when you do the hourly math, most authors make poverty level money, so why not pick the publisher you'll like the best? To find out which publisher fits you, you can either write for/flirt seriously with them or ask around. To save you the trouble of the former, I'll give a brief overview of the publishers with which I'm familiar:
     

    • Microsoft Press. This is the big dog that all the other publishers a) think is given an unfair advantage and b) are constantly trying to get within striking distance of. MS Press is so far ahead on sales volumes that the rest of the publishers are scrambling for #2. I've never written for MS Press, but have seriously flirted with them enough to be scared by them. This was years ago before the great opening of MS and things may be different now, but at the time, MS Press seemed keen to "fix" my writing to fit the "official" story and to be very firm about schedules, neither of which made me happy (I was used to a more loving, lax environment : ). Plus, MS Press is famous for little clauses in their contracts for which authors need to watch (although all publishers do this -- watch out for the one called "Right Of First Refusal").
       

    • Addison-Wesley. I've written all but one of my real books for Addison-Wesley and they have set the author environment standard against which I measure all others. In the old days, they'd throw advances and even grants at anyone with a pulse and then expect you to take 23.5 months to deliver on a 9-month contract while leaving you free to say pretty much whatever you wanted. Sadly, those days are over, but the idea of letting the author be the ultimate arbiter of what goes on the page has stayed. This comes from editors that are more like project managers in that they send nag emails when you're late and send chapters off to reviews to gather feedback, but don't ever really read the chapters (most AW editors aren't technical). What this means is that you have a lot of freedom as an author until some reviewer you don't agree with brings up something silly that the editor takes as gospel and whacks you with it.

      Luckily, if you're writing for an AW series, you'll have someone technical that can read and review your content, although in this case, you'll want to make very sure that you see eye to eye with your series editor or you'll find yourself butting heads.
       

    • O'Reilly & Associates. I've only written one book for them and it was a mixed experience. On the one hand, it was the wrong book (it should've been a Visual Studio Hacks book, but this was before the Hacks format was invented). On the other hand, ORA editors actually read the book and provide intelligent, thoughtful feedback. I really like that. On the gripping hand, ORA has built its reputation of steady quality by applying heavy copy editing to all of their authors to coerce those that aren't writers into the ORA "voice." Most of the time, this works nicely. If you pick up any ORA book in any series, you know what you're getting and lots of people love that (I love a lot of ORA books myself). However, if you're an arrogant author (like me) who thinks that he writes better than the copy editors, you may be surprised with what the copy editor does to your stuff.

      Also, ORA doesn't really have series so much as formats, e.g. Nutshell, Hacks, Developer Notebook, etc., so make sure you like the gimmick associated with a format before you sign up for one. To maintain that steady level of quality, they're going to make sure you stick to the format closely.
       

    • APress. I don't know a thing about APress except that I like Dan Appleman, Gary Cornell is a character and a half, they seem to have some good books and I've never written for them, so naturally I'd like to write for them for some day (I mean, just because my wife doesn't allow me to fool around outside our marriage, why shouldn't I be able to fool around in another genre? : ).

BTW, a lot of these same principles can be applied to your article writing, too, but there you know what they're paying you up front. A bunch of my friends have done the math and for the same amount of work required to produce a book, they can produce articles that pay much better. But you're not writing for the money, right? (Please don't try to write for the money...)

Discuss

#1 Windows Forms Book

Wednesday, June 30th, 2004

I just got word from my publisher that, according to the industry-wide metrics they use, Windows Forms Programming in C# is the #1 seller in it's category week-to-week by a wide margin over everyone but Petzold (who I'm still beating, but by a smaller margin). And while Petzold has sold more copies overall, he had a 2-year head start on me and I'm gaining. Further, earlier today, Amazon.com had the book listed as the #5 best selling computer book (although it's at #10 right now with a sales rank of 459 and a ranking of 5 out of 5 with 52 reviews).

I normally try to toot my own horn a little more subtly than this, but the idea that I could learn Windows programming from the best-selling Windows book author of all time and then, 10 years later, beat his sales numbers makes me damn proud. Thanks to all the reviewers and folks that gave me feedback on the materials in my articles, to Shawn Wildermuth and Mike Weinhardt, who actually contributed material to the book and to Addison-Wesley for printing it (and then re-printing it, and then re-printing it... : ).

Discuss

A Man, A Plan, A Canal, A Librarian!

Saturday, June 26th, 2004

Can't come up with a better palindrome than "a man, a plan, a canal, Panama!"? Write a program and come up with one that's 17,000+ words. I love computers and what people do with them.

The most extreme thing I ever did along these lines is when my airplane was circling an airport for some unknown reason and the United flight attendant announced a contest to keep our minds off the dwindling fuel and the terrorists on the ground (oh, wait, that's Die Hard...). Anyway, she offered a free bag of peanuts (or something of equal value) to the person that could come up with the most words of 3 or more letters from the letters in the word "united" (Always Be Closing...).

Did I put my Tim Ewald-expanded vocabulary to work? Did I scratch words onto a cocktail napkin as fast as I could think of them?

No. In the limited time I had, I wrote a program that would come up with random combinations of letters in brute force fashion, then dumped the unique ones to a file so that I could use Word's spell checker to find the real words. I came up with 32. Did I win?

No. A librarian, using her own expanded vocabulary beat me with 34 (I had been running the program to generate 1000 possibilities to speed testing but forgot to flip it back to 10,000 when it came time to run it for real).

Did I stop there? Did I accept defeat gracefully, especially since it's pretty clear I had cheated in the first place?

No. I went home and learned the STL permutation algorithm and wrote a program that compared against a dictionary from the web to find the 72 words of 3 or more letters in "united" (including asynchronous updates to the UI as possibilities are checked [it takes a little longer, but it's worth it...]).

Now I carry that program on my laptop wherever I go, just in case I run into that damn librarian again...

P.S. I did get to use my program one more time against my mother playing Scrabble. I got my all-time high Scrabble score ever on that day. She still beat me. Did I mention she's got a bachelor's degree in library science? Damn librarians...

Discuss

My Experiments in Social Video

Friday, June 25, 2004

Because I'm a rarity at Microsoft, a remote employee, I've been conducting experiments in social video to increase my presence from afar.

Experiment #1: Mini-Me

My first experiment was a dedicated laptop for IM audio and video that sits on my desk in building 5. The idea was that anyone that wanted to chat with me could wander by my office and start an a/v chat w/ me nearly as easily if I was actually in the office. And then, when I'm supposed to be in a meeting, instead of requiring someone to bring their laptop, with a web-cam installed, and give it up to me for the duration of the meeting so that I could see folks, they could just grab the "mini-me" laptop from my desk and bring it to the meeting.

Sounds nice, eh?

Doesn't work.

The reason mini-me doesn't work as a stand-in for me in my office is because there's no standard account I can login with on my desktop, e.g. redmond\guest. The reason a standard account would be nice is so that I can leave it logged in all the time, tie its own .NET Passport to the account and put a shortcut on the desktop to make it IM me in video conference mode (I actually wrote an app that does just that). Unfortunately, it has to be an MS domain account so it has network access and if I leave an anonymous domain account logged in on a laptop all the time, that's an enormous security hole. And if I make folks that want a quick chat with me log in themselves, they'll will have to wait for their domain settings to migrate to the laptop, they'll have to login with their own IM account, they'll have to configure the web cam before using it and they'll have to remember to logout when they leave for the next person. Frankly, I'm not worth all that trouble when they could just call, IM or email me.

So, the mini-me laptop is a bust unless I can figure out a way to get Internet access without Intranet access inside the MS corporate Intranet without requiring everyone to log in w/ their own account to get it. Oh, and it has to be in a way that works with wireless so that they can haul mini-me to a meeting without having to haul along a cable, too.

Experiment #2: Maxi-Me

My 2nd experiment in social video went quite a bit better. Last week I gave two 1-hour talks back to back to the AZ .NET User Group, but the trick was, I gave them from my house. The setup was two computers on each side. One was for NetMeeting app-sharing (using MSN Messenger to request Remote Assistance works, too, but I can never get MSN Messenger app-sharing going). The second is for the video (the CPU load was too heavy to do both on one computer). Voice was done over the phone, which they put through their PA system. They also had two computers, both attached to video projectors, broadcasting my screen using one projector and my image using another (can you imagine how disturbing it must have been to see the giant, pixelated maxi-me? I shudder at the thought� : ).

The app-sharing worked well, as I was able to easily switch between PowerPoint and a Terminal Services session to my Longhorn box. The audio worked well because I insisted on 2-way audio so I could hear them ask questions (I hate talking into silence). The video was cool, because I could see them raise their hands, drift off, laugh, etc, but it required somebody sweeping the room on their end periodically (talking without seeing your audience is slow death).

Overall, it seems like folks were able to enjoy a remote presenter without too much trouble. Once I got 'em warmed up, the speaker phone and roving camera made Q&A very natural. I would try maxi-me again, although I'd love it if I could get mini-me working, too.

In general, I believe that ubiquitous a/v conferencing is inevitable. I just I'm just a bit ahead of the curve. : )

Discuss

My Day With Edward Tufte

Friday, June 25, 2004

I spent most of Thursday in a seminar given by Edward Tufte, the author of several seminal books in the area of data analysis and presentation (with another, Beautiful Evidence, in the works). I enjoyed it thoroughly and here's what I was able to capture:

Tufte's Grand Principles

The goal of good information design is to minimize the amount of time spent figuring out the design of the presentation of information (or even admiring it) and maximize the time spent reasoning about the information. Good designs should be as nearly invisible as possible.

Tufte: "The point of an information display is to assist thinking. Good design is clear thinking made visible. Bad design is stupidity in action. Chart junk is a good sign of statistical stupidity."

My favorite Tufte term is what he calls designers brought in to make boring numbers look interesting: "chartoonists."

Ed's Grand Principles of Analytical Design

  1. Show comparisons (this is big theme of Tufte's)
  2. Show causality
  3. Show more than 2 variables, as the world we're trying to understand is multivariate
  4. Integrate word, number and image (this is another big theme)
  5. Say from where the data came
  6. The value of an information presentation comes from the quality, the relevance and the integrity of the content, i.e. good design won't fix bad content.
  7. Use small multiples, e.g. showing multiple pictures of sunspots on the sun over time
  8. Show and embed scales of measurement because it's an essential part of the context
  9. Annotate everything and if the audience reads ahead � great, they're reading your material
  10. Use proven design templates (like those in Tufte's books)

Tufte: "Don't let the marketing people corrupt your presentations by eliminating detail. Chances are, the people looking at the information know more than the marketing people. People haven't suddenly gotten stupid just because they come to hear you talk. If people can read the financial tables and the sports tables from the paper, they can get read data from you." (The last point assumes a good design.)

In my own work, I often remove detail for clarity, but I'm very careful to leave enough details to keep context. I admit, it's a fine like to walk and hard to get right.

As a way to pack more data into a small space (and in an attempt to secure his immortality, imo), Tufte was inspired by Galileo's work to create a new kind of graphic meant to be integrated into a sentence as yet another word. He calls them "sparklines" (the sparkline is the graphic before each word):

Sparklines pack a lot of information into a small space and are a cool alternative to graphics that break the flow of thought and need to be called out with a phrase like "as seen in Figure 3." I have a mind to implement them in Avalon when I get a chance.

90% Content

Tufte hates most kinds of user interfaces because they spend too much of the already low resolution screen on "fluff," e.g. menu bars, captions, navigation, etc, and too little on the content itself. As an example, he showed a screenshot of a photo display app that used only 18% of the screen for the actual photos. He wants nearly invisible operating systems and apps and 90% of the screen used for the content. He's a big fan of Google News as a way to pack in a lot of information and he's a big fan of scrolling. For web sites, Tufte recommends only a small set of links at the top of each page for navigation and nothing else. His own site is like this and I have to admit, I like it.

Design For High Resolution

Ed hates low resolution. He wants everyone to design for high resolution to be viewed at 22 inches so you can pack a lot of information in, showing comparisons and causality. He hates PowerPoint because it's made to be viewed from 22 feet and doesn't provide a lot of room for showing dense data, comparisons or causality. It's far easier for humans to make judgments when they can see everything at once instead of sequenced one slide after another (or "one damn thing after another," as Tufte says : ). In general, he believes everything should be printed and that PowerPoint should only be used for showing pictures to an art class. I see his point, but ironically, when he wrote a paper on the problem of PowerPoint to be read at 22", after 3 pages of him blaming PowerPoint for sloppy thinking, I put it down in disgust. If he had had his thoughts put together into PowerPoint-style format, I could have skipped ahead to find his real point, i.e. low resolution makes it hard to do serious analysis.

As a point for Tufte, when producing this summary of my day listening to him, I'm mixing prose, images and references, but I'm not producing it in PowerPoint. According to Tufte, 4 pages of prose is equivalent to between 50-250 PowerPoint slides and I have to admit, it would be hard to convey what I want to say about him in a PowerPoint deck without using a lot of slides and throwing away the subtleties. In general, I believe that PowerPoint is best for reminding the presenter what they want to say and is very poor for the audience. Instead of a slide presentation, Tufte recommends providing the audience 4 pages of prose, which they read 3-5x as fast as you could say it, and then having a conversation. Interestingly, he allowed no conversation during his own presentation but instead talked to various parts of his books and hand-outs.

 On the other hand, has anyone even read this far? Would you have gotten farther if I'd have summarized everything in slides, skipping ahead to the juicy bits when you got bored?

Giving Presentations

Tufte has a great deal of advice about how to prepare for and give presentations. To prepare, you must have great content (no amount of design or practice will fix bad content) and spend a great deal of time practicing (especially important if you're not using PPT to remind you what to say). When presenting, follow these rules (these aren't all of my rules, but I agree with them):

  1. Show up early to avoid problems and greet everyone at the door to learn their names, introduce yourself and begin advancing your cause
  2. Start talks with The Problem, Why They Should Care and The Solution
  3. Never start your talk with an apology, as it just make you look pitiful
  4. Use Particular/General/Particular when presenting information, e.g. start with a particular example of something, generalize it and then show another particular example that shows the same general characteristics (I use this technique all the time and it's very effective)
  5. Use first person singular only to express opinion, i.e. this isn't a talk about you but about a serious topic
  6. Give everyone at least one piece of paper (Ed prefers a single 11" x 17" folded in half with 4 sides of content)
  7. Knowing your content and respecting your audience is more important than knowing your audience if by "knowing" them, you "dumb down" your talk for them
  8. Avoid project slides (aka PowerPoint or the equivalent)
  9. Use humor as appropriate, e.g. hyperbole to make a point, but don't tell jokes. "Don't alienate your audience because of a joke. Alienate your audience on the merits on your content!"
  10. Avoid the use of "he" or "she," e.g. "The user, he takes his mouse and moves it to his menu bar where he makes his manly choice." Use "they" instead.
  11. Make sure folks know you believe what you're saying by getting out from behind the podium, getting close to people and use appropriate gestures. If you don't believe what you're saying, they're not going to believe it.
  12. Finish early and something good will happen. No one will ever look at their colleague, commenting on how they wish you had gone on for another 20+ minutes.

I think that Ed has enough good things to say about how to approach the presentation and analysis of data that I would recommend that pretty much anyone involved in the presentation and analysis of information take the time and attend his day-long seminar.

Discuss

My First Presentation For A Distinguished Engineer

Monday, June 7, 2004

Wednesday was a good day. Not only did I get birthday wishes from all over the internet (thank you, Orkut), but I got to give my first presentation to a Distinguished Engineer (or DE, as we call them in humble tones). A DE is the top end of the individual contributor ladder that technical folks who want to stay technical -- aka avoid becoming management -- are on. Architects, e.g. Don, are one step down on that ladder and Program Managers (PMs), e.g. me, are even further down. In this case, the DE to whom I was presenting is someone that I've long respected and who invented and continues to guide my favorite programming language: Anders Hejlsberg.

A couple of weeks ago, Anders was digging through our docs on a topic in which he was interested because of the future directions he's got in mind for C#. However, the particular information that Anders was looking for wasn't in our documentation. So, he mentioned that he'd like someone to look into it and get the information for him. As a percentage of the 56K employees at MS, there are a very few DEs, so when one of them mentions that they'd like to see something done, that's what happens. This doesn't happens because a DE is your boss or because they decide whether you get a raise or not. This happens because smart technical folks get respect at MS and the smarter you are, the more respect you get. So, when Anders mentioned to BradA that he would like a brief on this technology, Brad found someone to give that brief: me.

Why me? Well, lately I've been talking to Brad about me doing some more technical work on WinFX and Longhorn. In the past, I've written and spoken a great deal about the good and the bad of various technologies and my thinking was that if I could get into a feedback loop with the product teams so that I could help prevent some the worse bits from making it out the door, giving me the opportunity to write only nice things about our technologies. Brad already runs the WinFX review team that's in charge of making WinFX a nice place for developers to play, so when I volunteered to help with some of that work, it didn't take long for him to take me up on it. And, after a few moments of hesitation when I realized that I only knew a little more than Anders about this particular topic, I jumped at it, digging into the technology, sending "tell me more" and "review these slides, please" emails to the various product groups in charge of those technologies (it's amazing how quickly you get a response when you put "I'm writing a presentation on your technology for Anders and..." into an email : ), revised the slides, woke up in the middle of the night with the perfect set of pictures to illustrate things, etc. In short, it was a blast and I learned a ton (which you know I like : ).

And the actual presentation was even more fun than the preparation. There are three kinds of talks. One kind of talk, which happens 80% of the time, is the kind of talk that doesn't really affect you one way or the other. It kind of blends in with all of the other talks you've given and doesn't really make an impact on you.

One kind of talk drains you completely. This is the talk where you just can't get anyone to notice you at the front of the room and you pour all of your energy into it to make it acceptable at all.

And one kind of talk, my favorite, is when the juices are really flowing and you walk out of the meeting all excited and energized. This is the kind of talk that drives me and my colleagues to all-night diners for a debrief session. This last talk was the kind that I had this time with Anders and a couple of the product teams from around the company. I was really just guiding the discussion, with Anders leading and peppering all of us with wonderful, insightful questions. I had 20+ slides with overview, pictures, details and recommendations, but I only showed 4 of them (3 of pictures and 1 of recommendations). My inability to get through all of the slides didn't matter: Anders got it all. He was interested in some of what I had to say, but also brought up points I'd never considered. What I think should be in our platform was changed by just listening to Anders ask questions. I could feel the synapses in my brain realign. It was amazing.

Things will absolutely change in our platform because of the desires that Anders expressed during my presentation. What a privilege.

Discuss

Jury Duty

Friday, May 28, 2004

Today was the first time that I was called to jury duty, even though I've been eligible for almost half of my life. I always dreaded being called when I was a consultant because the $10/day didn't cover a day's meals, let along the revenue I would miss as the sole breadwinner of the family. However, much like the body puts off illness when you just can't afford to take the time (stress has its uses), my dread seems to have put off my jury duty 'til I had a full-time job with enough redundancy to live w/o me for a day or so.

Even when your job pays, most folks seem to want to get out of jury duty in any way possible. George Carlin says that the best way to get out of it is to admit to the judge that you know how to tell if someone is guilty, "It's all in the distance between their eyes..." Personally, I'm a believer in America's system of justice (I've often fantasized about a life as a prosecuting attorney and as a judge), so I didn't mind serving my turn on a jury. Unfortunately, it was not to be. While I went down to the court house, my number wasn't even called to appear on one of the two juries needed today.

Doing a little math, I found out that the overall odds of me actually being on a jury were actually pretty low. Here are the stats:

  • 47 people showed as potential jurors on 2 juries

  • 28 were called for the 1st jury, of which 12 were needed

  • 15 were called for the 2nd jury, of which 6 were needed

  • According to the State of Oregon Washington County Jury Director, 70% of people that show up for a trial see the assembled jury and decide to take the plea bargain after all

  • Therefore:

    • Folks called to jury duty that were actually put on a potential jury: 91.5%

    • Percent of juries, once formed, that are used: 30%

    • People called for a jury actually placed on that jury: 42%

    • My chance of actually serving on a jury today: 11.5% or less than 1 chance out of 8

    • The opportunity to make the US justice system real for the brothers Sells w/o them actually committing a crime: priceless

Discuss

Strengths and Weaknesses

Friday, May 21, 2004

I took a Gallup questionnaire and 3-hour seminar on the philosophy of strength-based development. The central idea is to identify one's strengths and concentrate on those. This is opposed to general thinking which says that you should work on your weaknesses. According to Gallup, no one can really change their weaknesses much, but if you focus on your strengths, you can really make a difference in yourself.

As evidence of this claim, Gallup sites a study of teaching speed reading to average and above average readers. The average readers started at 90wpm and the speed reading course increased their speed to 150wpm, an increase of 67%. The above average readers started at 350wpm and increased by more than 800% to 2900wpm. Or, to put it another way, it was 10x more effective to concentrate on a strength than to try to improve a weakness.

The dark subtext of the strength-based point of view is that if I can't really fix my weaknesses, then I can only really do well in certain kinds of ways. I don't like this idea. It sounds too much like fate, which just pisses me off because I don't like the idea that it's my nature and not my effort that determines how well I do at something.

When I mentioned this to one of instructions of the seminar, she looked at my strengths and said, "Oh, I see why you want to think it's you that governs how well you do," which didn't make me feel any better. My strengths, in order, are Achievement, Command, Communication, Learner and Intellection. In other words, I like to get things done, tell people what I think, learn new things and think about them. This set of strengths wasn't really a surprise, but here's one: I think DevelopMentor was speed reading for my particular strengths. DM was an environment that encouraged all of my strengths and I stumbled onto it by pure, dumb luck.

On the other hand, before DM, I wasn't nearly the Communicator that I am now. In fact, I think it would've been one of my weaknesses had I taken the Gallup questionnaire 10 years ago. And if that's the case, I would have been discouraged from spending too much time working on it by, for example, teaching, presenting at conferences and writing courses, articles and books, which I think would've been a shame, because I really love to write.

So, while I like the idea of concentrating on one's strengths, I still don't like the idea of ignoring one's weaknesses.

Discuss

Another Killer App for Web Services

Friday, May 21, 2004

At the last Applied XML Dev.Conf., I went ga-ga over Amazon's use of web services in their business and called it the "killer app for web services." Now I'd like to revise my statement: it think that it's one of the killer apps for web services.

Here's another one: exposing the functionality of all of those internal corporate services apps that are now exposed as web sites as web services instead.

Now that I've been back inside of a giant corp. adrift in a sea of sites to "help" me with the various "business processes" that I have to execute, I yearn for them all to be exposed as web services. There are several problems with the internal business-processes-as-web-apps morass that we're stuck in:

  1. The web apps are generic for all uses across all companies, which means that there are tons of options for other uses then mine, but I still have to deal with the UI for all of the options

  2. To get my business tasks accomplished, I have to string together several of these web apps in series, manually moving the data from one to the other

  3. Just going from one page of a web app to another, even in a corp. intranet, is so slow when you are always going to pick the same options and your fingers want to be far ahead of what the server can handle when generating the UI a page at a time

For example, here at MSDN, we have package source code sent to us by authors into an MSI with a EULA, code sign it with the Microsoft key and submit it for download to the MS download site. A year ago, it took me an hour of instruction to understand the process and it involved using VS.NET to build the MSI and two separate web sites, both with several pages and tons of fields to get a folder of files available for download by our good readers. This took me 30-60 minutes to do each time I had to do it, which made me cranky, so I built this:

This tool takes the minimum number of fields necessary to turn the source files provided by the author into a signed MSI. Plus, it's a smart client, so the UI is snappy and I can make it smart about what specifically it should remember between sessions for our own uses. And, I can provide a single UI for multiple back-end services, duplicating the data between them as necessary w/o requiring the user to duplicate the data for me.

The way I was able to minimize the number of fields was to build all kinds of assumptions into the app based on how MSDN does things, aka the business rules, and build my own app that programmatically generates when I need. In other words, my app combines business rules with programmatic interfaces to save me and my friends all kinds of time (the process is now about 10x faster than it used to be and 100x less tedious and less error prone).

And that's the beauty of allowing programmatic access to internal business processes: it allows each group in the company to build specific apps that meet their needs more specifically, letting them consolidate the processes into their own group-specific tasks. Not only does this speed things up and increase consistency for our customers, but it also removes the tedium and lowers the possibility of human error. If you could gain all those benefits, would you do it? That's the promise of web services and SOA when applied internally, because it allows the groups that provide the services to be general-purpose, meeting the needs of all groups, but lets each group be specific when they apply it, instead of forcing a web interface that requires everyone to be general.

Am I alone in getting aroused when thinking about this kind of thing? : )

Discuss

3 Years of Spouting

Sunday, May 16, 2004

Yesterday was my 3rd anniversary of The Sells Spout. It's hard to remember back that far, but this was before any wide-spread blogging software, either client or server, before RSS and before personal email addresses were rendered nearly useless by 157 messages/day about how to enlarge our genitalia, necessitating the eventual move away from newsletters.

At the time, I used FrontPage and <a name> tags to run my blog. I still use FrontPage + <a name> tags, but I also use web forms and SQL Server to track comments and generate RSS. In general, I see my site as a giant, categorized blog, e.g. Tools, Fun, Spout, etc, with a front page of descriptions of the items I add to my site and of interesting things I find in the world. Towards that end, I'd like to rebuild my site from scratch using some kind of content management system so that I can get a bunch of flexibility that I don't have now, e.g. referral logs, auto-archive pages, comment notifications for me, rich comments, a smart client front end for reading from -- and adding content to -- the site, etc. I could add all of that to my own homebrew software, but I'd prefer to use something like .Text. In fact, assuming ScottW integrates .Text into ASP.NET 2.0, rebuilding my site with both is something that I've very likely to do.

The site itself is 9 years old, but my normal outlet of tools, code samples and technical writing wasn't enough for me, so 3 years ago, I started editorializing on The Sells Spout. I don't know what my site traffic was 3 years ago, but I know it's grown ridiculously since then for no reason that I can discern. For example, last month my site served 885K sessions and 2.5GB in small pages, zip files and RSS feeds. While full 55% of the page hits were the RSS feeds (quite a number of you are keeping a close eye on me, apparently), that left 398K people/month visiting my site to read or respond to a topic from my blog (18.7% of the total), read about interviewing at Microsoft (10.6% of the total) or download a tool (4% of the total).

BTW, for those of you who would point out that my RSS feed is syndicated as the Editor's Blog for the Longhorn Developer Center, throwing off my site stats because of the traffic on the DevCenter itself, I'll counter with one word: caching. Kent Sharkey, the editor of the ASP.NET Developer Center and expert in all things ASP.NET, has built caching into the control that displays the Editor's Blog from my RSS feed. Since it's set to 60 minutes of cache per server and hosted on the 11-server MSDN web farm, that's at most 8184 sessions/month to serve my RSS feed on msdn.com.

I don't really know what draws that many people to my site, but 3 years ago, I stated my rules of engagement as follows:

  • I want to make people's lives better.
  • I'm interested in putting food on my table.
  • I'm interested in what I'm interested in.

    After 3 years, my agenda remains the same. I find that strangely comforting.

    Discuss

  • The Advice of Our Fathers

    Friday, May 14, 2004

    Being a Midwesterner, my father is a fairly stoic man and, unlike his son, doesn't often speak just to hear the sound of his own voice. Still, I've managed to pick up a few gems over the years that my own sons are now forced to hear often, like "If something is worth doing, it's worth doing well," "It's the hard things that are worth doing," and "It's easy to figure out the right thing to do -- it's the hardest" (do you detect the Midwest work ethic in any of these sayings? : ).

    When I was having trouble with a pair of 6th graders (I was a 3rd grader), he said, "Don't start a fight, but make sure that you end it" (that was hard to implement...).

    When I went off to college, he said, "Don't go to bed drunk" (I always regret it when I ignore this piece of advise...).

    When I broke something of my wife's and wasn't contrite enough, my father, working on wife #3 at the time, said to me, "You've got to be nice to your wife!"

    But the one that sticks with me most, the one I hear in my head almost every time I make a sandwich (and the one that caused me to write these words) is "Don't get the God Damn jelly in the God Damn peanut butter!" To this day, with my father 1500 miles away in Fargo, I still make sure that there's no jelly on my knife when I reach for the peanut butter.

    It's funny what unintended impressions you leave on people. I wonder what about me will haunt my children?

    Discuss

    Post/Reply Alphabet Soup

    Sunday, April 25, 2004

    Newsgroups, mailing lists, web forums and blogs (with comments) are all very similar. Fundamentally, they'll all about posts and replies. Sometimes the posts are replicated to servers around the world, acccepting replies in the same way. Sometimes the posts are replicated to a set of subscribers via SMTP and replies come in via POP3. Sometimes the posts are part of a web page and provided via HTTP, using HTML forms to take replies. Sometimes the posts are served up via a centralized server using HTTP + RSS or HTML, accepting responses via HTML forms or the CommentAPI. Fundamentally, it's all the same thing, though: posts and replies. Why do I have to suffer with the limitations of any one of these protocols just to hang out with my friends to talk shop?

    I don't like newsgroups because I don't like having a separate reader outside of my mail reader (and NewsGator ain't anywhere close to what I want yet). Plus, newsgroups are very susceptible to spam, although the MS newsgroups are carefully patrolled to kill it before it spreads.

    I don't like web forums because I either have to poll the site (which RSS has cured me of) or the integration of the forum into my mail reader is limited to notification only. Plus, every single web forum has a vastly different UI and set of features and the inconsistencies bug me. On the other hand, web forums are pushing the envelope on features that I really want, like author and content ratings.

    I love mailing lists, but don't want to duplicate any of the WinFX newsgroups in mailing lists just yet to avoid fracturing the budding developer community.

    Blogs are wonderful, of course, and RSS is the only thing that's worth me spinning up a whole separate reader than my mail reader, but it's impossible to follow a thread of conversation between blogs or comments on other people's blogs. On the other hand, the server-per-poster model is great because I can just subscribe to the posters that I like, increasing the signal to noise ratio substantially.

    I think we should pack all of the features of mailing lists, newsgroups, web forums and blogs into a single backend and expose it via HTTP, NNTP, SMTP/POP3 and RSS as appropriate. Is it time for a new protocol that can be dumbed down to the existing protocols for the diehards that won't give up their readers of choice? Personally, I'd like to get everything via SMTP/POP3 except for my RSS feeds (although I don't know why -- maybe it's just that I can't seem to get a handle on a keyboard-only mode for RSS reading in NewsGator the way I can in SharpReader...).

    Discuss

    Freeing My Mind

    Saturday, April 24, 2004

    I'm a sucker for new experiences. It's not that I believe that "you only go around once," because I don't believe that. I believe that our job on this plane of existence is to raise our level of consciousness to the next level and that our souls are recycled from life to life on this plane 'til we're ready for the next. So, I figure that anything I don't get to do in this life, I can do in the next.

    And yet, I'm still a sucker for new experiences. In any given 10 years, most folks get 1 year of experience 10 times, but I think I've done pretty well at squeezing quite a bit out of my last 10 years. And I hope to continue to do that. For example, this year my wife and I will be attending Burning Man. We'd never been, but a couple of my friends from MSDN are helping us find our footing at what promises to be a very unique experience indeed.

    MSDN is, in fact, a haven for unique folks willing and able to help me try new things. As another example, last week I had a private meditation lesson from Henry Borys, MSDN editor, book author and meditation teacher for the last 30 years (he's been teaching meditation since I was 4!). He runs weekend seminars and even a yearly trek to the Himalayas and while both sound attractive, my Redmond travel schedule almost never brings me there over a weekend (let alone to the Himalayas : ), so he invited me up to his place for a private lesson. It was beautiful. It was 30 minutes north of the hustle and bustle of the MS campus and right on the shores of the Puget Sound. We sat on his back porch, watching the sun set over the water and talking about his experiences in meditation (mostly in variations of transcendental meditation [TM in meditation speak]) and my experiences applying what I'd picked up on my own reading Meditation for Dummies (I have come to love the Dummies books).

    We spent almost two hours meditation and discussing meditation. Here's what I learned:

    1. Meditation should be effortless. If you're working at it, you're not getting it.

    2. Don't fight the thoughts to "clear your mind." That's a sure way to keep them bubbling in your head. Instead, think of thoughts as the by-product of the purification of the mind that happens when you meditate and let them happen w/o paying them any attention.

    3. When you find yourself dwelling on your thoughts, go back to your mental mantra. Henry, as is traditional in the meditation teacher-student relationship, assigned me a mantra. Mine is a general-purpose and commonly shared amongst TM parishioners, but is still darn exotic to me, being in Sanskrit. The mere sound of it helps me and, since I don't really know what it means (although I'm hoping it's not "send Henry money" in some subliminal form : ), it doesn't distract me from the meditation (unlike my previous, self-chosen mantra "free your mind," which, while very meaningful to me, did tend to hinder).

    4. You're not meditating for the act of meditation itself, but the benefits it adds to your life when you're not meditating. While I've grown to like the act itself, I have also been enjoying a more peaceful, less stressed perception of life since I started (although it's still too early to tell if this is merely the placebo effect).

    5. Don't judge your meditation. Let it happen how it happens.

    6. Your meditation may uncover some deep-seated sleep that's necessary for your body to experience, so if you feel yourself falling asleep while you meditate, that's OK.

    7. Take 3+ minutes to come out of your meditation to "avoid the bends." Otherwise, you could easily come out of it too quickly, giving yourself headaches and/or making yourself irritable. I find that 60 seconds is enough for me, but I'm sure I don't get anywhere near as deep as an expert, so I always take this process as slowly as I can.

    And one of the most fun techniques that Henry introduced was to realize that thoughts are merely interactions with your consciousness. This realization can make your thoughts abstract, which can actually push you deeper into the meditation itself. In other words, when you think of thoughts this way, the more you have of them, the better, which was non-intuitive to my previous understanding of meditation. Hearing this was a very "there is no spoon" kind of moment to me.

    I was actually looking for some kind of introduction to meditation for months before I learned that Henry was a teacher, even though I've known him for more than a year, showing that once again, when the student is ready, the teacher will appear. I look at this experience as help along the way to a higher plane of existence, which I believe is defined within. And while I'm not a practitioner of any religion (I'm ex-Catholic), I do see this as a spiritual pursuit, blending the beliefs I've picked up with my brief brushes with Gnosticism and Buddhism and as popularized in The Matrix (although lost again in those stupid sequels). Free your mind, indeed.

    Discuss

    More On The Quest To Kill Code

    Wednesday, April 14, 2004

    You're remember the last installment in my continued quest to find the next big leap in program producing productivity (the last two were OO and managed environments), where I thought I had it all figured out with generic algorithms. All we need is a sophisticated enough environment and wham self-writing, self-maintaining, self-debugging algorithms baby. However, after this evening's Portland Nerd Dinner (you didn't pass up a chance to meet Ward Cunningham, did you?), I'm thinking there's one step in the middle (at least : ).

    So, picture the scene. After hearing about a guy that has a "fob" on which he has to enter a password to get a 6-digit number that changes every 60 seconds to that he could log into his company's VPN, declaring that that's what happens when you let Keith Brown run the world (I love you, man : ), and describing the CSSM (the Chris Sells Security Model -- which I can not only implement under .NET, but actually apply to code [maybe I'll start a workspace...]), I turned to Ward and asked him the same question that I had asked the group from the last PND, i.e. "What's the next big leap away in development?", being careful not to give him my thinking from last time.

    Ward went a whole other way.

    And he got me thinking it's a good idea.

    So, Ward starts describing how to use loose typing (as in computer science "types" and what you do with your 101-Key Text Wizard) and TDD-style tests to infer types for your loose typing and I'm shaking my head, 'cuz I still gotta write the code.

    Then a long-haired guy to my left who's name I never lernt (I meant to!), starts talking about how each leap in the past came from handling one detail that you don't care about, e.g. register allocation, memory management, etc, and I think that has the possibility of helping me, 'cept the thing I want to get rid of is the code (I mean, if I can't make a business on generating the stuff, then let's kill it altogether : ).

    Then Jim Blizzard starts asking an interesting line of questions about whether a leap is really a leap 'til we're passed it and we can look back and decide it was a leap. While I think a leap is a leap because you can feel it (I can still remember the joy of my first program [leap 1], hear the ping in my head when I understood OO [leap 2] and feel the rush in my veins when I got managed programming [leap 3]), I was very interested in Jim's point because I think he was leading me somewhere [leap 4?].

    Then, Ward jumped in again with another scenario where you start from nothing and have a programmer at your elbow to translate the next thing you want as you desire it (the first such scenario was Ward's Adventure Diet where you start with nothing, then add one kind of food/day 'til you pass the unit tests I guess [Ward actually put himself on this diet for a while -- man, we are nerds]) and that's when I nearly leap across the table so that I can get my own words in edgewise, literally telling Warm that he had to stop talking now so that I could.

    Because that's when it all hit me.

    What I want is X1 for programs. I've fallen in love with X1 because it gives me immediate gratification. It still finds the same things that Outlook search and Explorer Search finds for me, but X1 does it in such real time that I can narrow in several fields at once based on what I know about what I'm looking for, e.g. some of the body content and/or who it's from and/or what folder it's filed in and/or when I got it, etc, until I see a small number of choices from which to pick and I can click on one and say "aha! that's the one!"

    I want X1 for programs. I want to start with nothing and keep refining it with commands like, "I want an app," "I want a grid" and "the data should come from here" and have my computer say, "Would you like an app like this, this or this" and "would you like the grid to look like this, this or this." And I want my computer to know about every feature that ever been built into 3 or more programs, e.g. from remembering the spot my window was the app last ran to dropping in pivot tables, from reading/writing to/from databases to providing theming. Anything that doesn't work in 3-6 choices, e.g. color themes do but individual colors don't, I want a Property Browser/Windows Forms Designer-like experience and only when I get to implementing something that hasn't already been implemented 3 times do I even want to think about writing a line of code.

    'cuz here's the thing. I don't want to give up writing code. I love writing code. I just hate writing code that's already been written. What I want is for a customer to go through all of the stuff in the Codeless, Human-enabled, Realtime, Interactive System (or CHRIS*, if you will : ) as described in the previous paragraph, get to an actual working system except that it doesn't do some cool, unique thing that no one's ever thought of before and then send it to me in an email along with a PO for how much they're willing to pay for me to do the last bit.

    When the last bit's been written 2 more times, it goes into the CHRIS and around we go again.

    And I was all happy with that answer and I presented it the PND crowd just before the Sells Brothers (who had come along and been absolute angels for more than 2 hours while I geeked out with my friends), lost it and started throwing their shoes at each other in the Washington Square Mall food court, at which point I had to leave, before hearing what Jim's point was or what Ward was going to say after he said, "OK, wait, what about this..." which is usually what he says just before he tells you that he's already built what he's been warming up to for the last 30 minutes and you find that it rocks.

    So, you guys damn well better tell me what happened after I left, especially if it's better then the CHRIS!

    BTW, why isn't anyone filming these PNDs? They're the best techie conversations I have all month...

    Discuss

    * I swear that 90% of that acronym (abbreviation?) came out naturally and was only tweaked slightly at the end for marketing appeal. : )

    I'm Loving the .NET Fx ARM

    Saturday, April 10, 2004

    I enjoyed the annotations in The .NET Framework Standard Library Annotated Reference so much that I read them all in one sitting (in the bathtub, if you must know...). The annotations are where the authors put in their 2 cents about a particular class, method or property and it was very interesting. Here's what I learned just from that part of the book:

    • You shouldn't use ApplicationException for custom exceptions. Derive from Exception instead.
       
    • Because ICloneable.Clone doesn't define whether it returns a deep or a shallow copy, it's practically worthless.
       
    • Prefer UTF-8 because it takes up the same amount of space to represent ASCII characters as ASCII, but can also represent all Unicode characters (I knew that UTF-8 took up the same amount of space but hadn't yet jumped to "prefer").
       
    • I was reminded of the System.Convert class, which does all of the same conversions that the various type-specific ToXxx and Parse methods do, but puts them all in one place.
       
    • There's another use for the private interface method implementation syntax in C#:
      class Enum : IEnumerator {
        object IEnumerator.Current { get { return this.foo; } }
        ...
      }
      This syntax hides an interface method from general use unless you cast to the interface base class:
      Enum enum = new Enum();
      object obj1 = enum.Current(); // compile-time error
      object obj2 = (IEnumerator)enum.Current(); // this works

      The thing I never thought of that this enables is that it lets you override based on return type, which isn't normally allowed in C#:
      class Enum : IEnumerator {
        object IEnumerator.Current { get { return this.foo; }
      Foo Current { get { return this.foo; } } ... }

      This private method implementation syntax lets you return the generic type as part of the interface implementation so that you can plug into standard idioms, e.g. foreach, but a more specific type for users of the type directly, saving the cast:

      Enum enum2 = new Enum();
      Foo foo1 = (Foo)((IEnumerator)enum.Current());
      Foo foo2 = enum.Current(); // no cast required
      This will be less interesting as generics take over, but still, it's a useful trick.
       
    • DateTime is always assumed to represent local time, so if you convert to Universal time twice, you'll change the value each time.
       
    • Since it's possible to cast any number to an enum value, e.g. TrueFalseEnum tfe = (TrueFalseEnum)42, make sure to always check that an enum is a legal value. Theoretically this is a pain, but in practice, I tend to check enum values with switch statements, making the default case the error case, so it's good to know that my code does the right thing.
       
    • The Threading.Interlocked class.
       
    • Jim Miller has way more birthdays than we do. : )
       
    • Jeff Richter agrees with me that the ThreadStart delegate needs an object parameter.
       
    • I should be using CompareInfo instead of ToLower for case-insensitive comparisons (although they don't show how):
      using System.Globalization;
      using System.Threading;
      ...
      CompareInfo compare = Thread.CurrentThread.CurrentCulture.CompareInfo;
      if( compare.Compare("foo", "FOO", CompareOptions.IgnoreCase) == 0 ) {
      Console.WriteLine("the same"); }

    If I can get that much out of just the annotations, imagine what I could learn if I read the whole thing. : )

    Discuss

    Filling In Missing Computer Science Knowledge

    Tuesday, April 6, 2004

    Sometimes I get emails from folks that don't have a formal computer science knowledge and want the benefits of one w/o actually going back to college. Since I was disappointed in my own formal education (despite going on to "better" my BS in Computer Science with an MS), I can understand this desire.

    My first thought was the MIT Open Courseware, which has a full course of computer science curriculum. However, while the course material is all there, unless there are officially sanctioned forums for each course, there's really no place to ask questions even of fellow students.

    After thinking on it for a while, I thought I'd go right to my favorite source. Prof. Joe Hummel is a professor of computer science at Lake Forest College in Illinois and has spent a lot of time thinking about how to fill in missing CS knowledge in professional programmers (VB programmers, mostly) at DevelopMentor. Here's what he said:

    For starters, I'd recommend a book by Brookshear called "Computer Science: an overview" (8th edition). It's written for those new to CS, but introduces lots of nice CS concepts like algorithm analysis, theory of computation (e.g. that some problems cannot be solved!), and other things like OS, networks, DBs, etc. It's a great starter book. After that, I'd recommend books on data structures and algorithms. After that, it really depends on what his interests are: Programming Languages? Theory? Operating Systems? Distributed Systems? Software Eng? AI?

    Discuss

    Let There Be Light In The Darkness

    Thursday, April 1, 2004

    I wrote this at the beginning of 2002 while channeling my energies into the Windows Forms book. I never published it, but I liked it (and I'm in writer avoidance mode as day #2 past my due date rolls by), so I thought I'd share it:

    The Dark Ages, a period of five centuries beginning in 5 AD, marked a time of intellectual darkness and barbarity. A ruling feudal class kept a firm grip on their over-worked peasants in small enclaves eking out a meager living from the soil. Only lonely, isolated monks were able to record knowledge using primitive tools to painstakingly inscribing it into hand-crafted volumes, each unique and each unavailable to their fellow man. Only pilgrims and adventures, willing to endure long journeys and brave many hardships, had the chance of obtaining this secret knowledge. Finally, the Renaissance, brought on by the spread of knowledge in approachable formats using inventions like the printing press, was able to rejuvenate a weary world and bring about a period of intellectual growth and achievement that continues to this day (interrupted only briefly by the Reagan years).
    The Browser Age, a period of ten years beginning in 1991, marked a time of user-interface limitations and lowest common denominators. A ruling standards body kept a firm grip on their over-worked participating members in companies large and small, eking out a meager living from IPO wind-falls. Only lonely, isolated web masters were able to record knowledge, using primitive HTML to painstakingly code it into hand-crafted pages, each unique and each unavailable to their fellow programmers. Only Perl programmers and regular expressionists, willing to parse tangled byte streams and scrape many screens, had the chance of separating the data from the presentation. Finally, .NET, brought on by the spread of the information available programmatically to rich client applications using inventions like Web Services and Windows Forms [ed: and soon, Avalon], was able to rejuvenate a weary software world and bring about a period of productivity growth and achievement that will continue until long after we retire (interrupted only briefly by the Internet Bubble burst).

    Discuss

    Checking Spec. Compliance at Build Time

    Thursday, March 25th, 2004

    Even though Ward Cunningham and I have been living only 4 miles away from each other for some years, I really didn't know that he lived in in the same state 'til he sold his soul hired on at Microsoft. Since then, we've been meeting at a local Starbucks on a regular basis to shoot the shit in a very DevelopMentor/Tektronix-like way, i.e. ramble on about whatever 'til we hit on something fun to try. In one of those meetings, we were talking about requirements for a web services API that I'm working on and he took us off on what I thought was a tangent, but turn out to be very cool.

    Before Ward set me straight, I thought that Test-Driven Development (TDD) was when I built a little console app to test my APIs. I routinely do this before I write an API so that I can imagine what I wish I had to program against without being encumbered with an existing implementation. Then, I run my console app(s) afterwards for testing and regression testing, but only sporadically. I knew that NAnt let me run these tests into my build process, but since I'm a VS.NET guy and I haven't done the NAnt/VS.NET integration work that I know I should do, I haven't done as much with this as I knew I should be. Plus, as it was only me, it didn't seem like such a big deal.

    What makes TDD a big deal, however, is when you've got a team of folks. Of course, every developer is expected to check in tests for their stuff and those would be run as part of the nightly build. But that's not the cool part. The cool part is when another developer adopts my API and puts his tests into my build process. When someone adopts an API that I build, then make certain assumptions about how it works and what side effects they can expect. TDD lets Joe R. Programmer encode his assumptions as unit test code so that when I break his assumptions during an iteration of my API, I see it as part of my compiler output.

    Until I get a build error, I don't need to know or care about Joe's test. But when I do, I look at Joe's unit test code and decide whether he was right. If Joe's unit test is valid, I need to either fix my breaking change or be prepared to help everyone that uses my API to rewrite and redeploy their code. If Joe's unit test isn't valid, I've got to help Joe fix his code and prepare to help everyone else that made "invalid" use of my API to begin with. The very nicest things about TDD is that "fixing breaking changes" becomes the least painful thing to do!

    This is huge. In fact, it's so huge, that MS should provide an end point for people to submit their own unit tests against our Windows and .NET APIs so that when we make breaking changes, we can either fix them or know the proportion of folks affected by this breaking change.

    Anyway, when Ward told me this, my eyes were opened and I was changed. But he was just getting warmed up. After showing me the power of formal unit tests across a team, he then went on to describe the power of putting the unit tests right into specifications themselves. For example, imagine a table in a spec laying out a series of inputs and expected outputs:

    Now imagine a parser that could read through this table and execute the code being specified, checking expected output against actual output, lighting matching output green and mismatched output red:

    This scheme lets designers define the spec long before it's implemented and then check it's progress as it's implemented. Likewise, a spec itself can be put into the build process as another set of unit tests. Plus, the readability and maintainability of specs in this format is much improved and very much more accessible then unit test code.

    But wait, there's more. This isn't some pipe dream. Ward has a .NET implementation of it called the FIT Framework on the web and yesterday he and I played around with it in my kitchen. Our goal was to take Ward's .NET FIT implementation and add support to it for SOAP endpoints. We started with the ISBN Information web service that we found on xmethods.org and defined the following spec:

    We specified the name of the FIT "fixture" (which is the class that implements the tests in FIT), as well as the WSDL URL, the service type and method we'd like to test, the arguments we'd like to test and the results we expected to get. We mixed in some of Christian Weyer's Dynamic Web Services Proxy and we got this:

    Notice that we're not quite done yet, i.e. nothing is green and we're not reaching into the retrieved XML and pulling out the Author, Publisher, etc. Still, while FIT requires a matching piece of code for every spec, we dropped a bit more metadata into the tables for the SOAP version, leveraged WSDL and have narrowed the project to a single piece of generic code for any WSDL-described SOAP endpoint (so long as Christian's code can parse it).

    Our plan is to finish up the extensions to FIT for SOAP and to put it into practice on the SOAP API that I'm currently designing and even to push it into our build process if I can. Further, I'd like to build another FIT fixture that, instead of executing the tests, generates sample code to demonstrate example usage and expected output (including expected errors). Rest assured, when we get it working well enough for public consumption, Ward and I will publish the SOAP extensions for your enjoyment.

    But don't wait for that! You can do TDD with custom actions in VS.NET 2003 and with the FIT Framework today!

    Discuss

    Avoid the GAC

    Thursday, March 11th, 2004

    The .NET Global Assembly Cache (GAC) is a misunderstood and misused beast. For all intents and purposes, it provides what COM and windows\system32 do, i.e. a machine-wide place to drop shared DLLs. Of course, the problems with sharing DLLs in a machine-wide spot is that it leads to a set of well-known problems collectively called "DLL Hell." There are many problems, but the biggest is that when a shared DLL is updated, you're really updating an unknown set of applications. If the set of applications is unknown, how can you possible test them before making this change? And if you can't test them, you're likely to break them. What this boils down to is that any of the shared spots for updates, whether it's a COM CLSID, windows\system32 or the GAC, are dangerous and should be avoided. And this is why the preferred .NET deployment scenario is "xcopy deployment," i.e. having your own private copy of each DLL that you test and deploy with the rest of your application.

    "Aha!" you say. "The GAC supports multiple version of an assembly! When a foo.dll is updated to v1.1, v1.0 sits right along side of it so that your app *doesn't* break!" Of course, that's absolutely true. But if that's the case, why do you care? I mean, if there's a new assembly available but your app isn't picking it up, what difference does it make?

    "Aha again!, you say. "I can put a publisher policy into the GAC along with my assembly so that apps *are* updated automatically!" That's true, too, but now, like any of the machine-wide code replacement strategies of old, you're on the hook for an awesome responsibility: making sure that as close to 0% of apps, known to you or not, don't break. This is an awesome responsibility and one that takes MS hundreds of man-years at each new release of the .NET Framework. And even with those hundreds of man-years of testing, we still don't always get it right. If this is a testing responsibility that you're willing to live with, I admire you. Personally, I don't have the moral fortitude to shoulder this burden. For example, we do sign genghis.dll when we ship it so that folks can put it into the GAC if they want, but we make no promise of backwards compatibility between versions and therefore we do not ship publisher policy DLLs. Instead, we expect folks to use xcopy deployment and catch the problems at compile-time and test-time.

    So, if the GAC represents such a massive burden, why do we even have it? It's for two things that I've been able to identify:

    1. Fixing critical bugs without touching the affected apps (and without breaking anything!)

    2. Sharing types at run-time between assemblies deployed separately

    #1 is what you get when you install Windows hot fixes and service packs via Windows Update. A ton of design, implementation and testing time is spent to make sure that existing code won't break before shipping these fixes.

    #2 is needed if you're going to be sharing types between assemblies that you can't deploy as a group but absolutely must keep to the same version of things. .NET Remoting peers are in this category, but only if they're deployed in separate directories so that they won't share the same set of types available via xcopy deployment. However, if .NET Remoting peers are deployed on difference machines, the GAC won't help you anyway as you'll be manually insuring the types are the same across machines. BTW, the responsibility of keeping multiple machines to the same set of types (and the same framework for hosting those types) spawned an entirely new way to talk between machines, i.e. web services, so .NET Remoting itself is something to avoid unless you can administer both ends of the pipe for simultaneous updates.

    Another scenario that fits into #2 is the Primary Interop Assembly (PIA). A PIA is a COM interop assembly that's been pre-generated and dropped into the GAC so that everyone that adds a reference in VS.NET to mso.dll (the COM library for Office) gets office.dll instead (the .NET Office PIA). That way, everyone can talk to the same set of types instead of everyone getting their own incompatible interop types generated on the fly. However, PIAs are primarily a way to make sure that VS.NET has a central place to pick up the shared types without regenerating new incompatible types.

    Notice that "Saving hard drive space" wasn't on my list of reasons to use the GAC. I just purchased a 60GB, 7200RPM hard drive for my laptop for a measly coupla hundred bucks. I don't want to hear about you jeopardizing the reliability of the applications on my machine to save a tiny percentage of that space. Hell, when I buy a HD, I give 50% of it over to apps anyway, so help yourself and keep my apps running by avoiding any machine-wide space for updating shared DLLs, including the GAC! Thanks.

    Discuss (did I miss any reasons to use the GAC?)

    Of Mixed Career Minds

    Tuesday, February 24th, 2004

    Don and I have an ongoing debate -- whether everyone was put on this planet for one purpose or whether a person gets to choose their path. This all started back in the middle of the bubble where we thought that we were so smart that we could take our success in training and turn our minds to anything we chose. We thought we could be anything, but used to talk most about politics (and Don even promised to get me elected as mayor of Beaverton) and religion (I'd like to get in on the ground floor of one of those "free love" cults : ).

    Of course, the bubble burst, giving of us perspective on just what part of the success was us and what part was the go-go economy. Now, most of us that used to have those conversations work at Microsoft as a place to keep doing fun work without traveling to globe trying to keep up our old standards of living. These days Don talks about all of us having a specific place in the world and that he's pretty darn sure that he's found his (and you should see the guy; he's in there, fighting for what he thinks is best for the platform and building quite an impressive reputation base to extend his influence wider and wider). He's also of a firm mind that I've found my place and that I should be a s/w guy of some kind for the rest of my life.

    So, I'm of two minds. On the one hand, I'm happy with the spot I've carved for myself in the Windows developer community and I think that there are plenty of fun s/w challenges to meet. Plus, my resume helps me get good gigs.

    On the other hand, I'm not a big fan of being "predestined" to anything. I don't like the idea that fate or even my inborn predilections decides what I do and don't do in my life. I also still think that I'm smart enough and flexible enough that I could start another career. My latest fantasies revolve around moving into a place that my wife could afford on her nurse's salary while I write novels and spend my afternoons filling the public education gap my kids are experiencing. Previous fantasies include getting my jurist doctor at Harvard and becoming a courtroom prosecutor on my way to being a judge (I always know what's best for everyone : ). Also, the equities market calls my name and I've got a little property investment business on the side that could use more attention. So, I've got plenty of things I'd like to dig into before I die that have nothing whatever to do with my background or training. In fact, I've got so many other things to try that Lutz was making fun of me just last night, "Haven't you noticed that everyone in 2004 wants a new career?" Still, should I stick with what's safe because I may never achieve in other industries what I've achieved in this one or should I roll the dice and takes my chances, knowing that life is pretty short to spend it all doing the safe, comfortable thing?

    Don't get me wrong; I'm not going anywhere just yet. I've started this Longhorn thing and I've got lots more to do there before I'm done. But I do think about hitting the reset button some day and starting over again from scratch. What do you guys think? Have any of you hit the reset button and ended up reading this post? Has anyone tried to escape from this industry only to end up back here and are happy they did? Does anything think that my hubris is going to get me into serious trouble? : )

    Discuss

    On Behalf of Software Engineers, I'm Sorry

    Sunday, February 1st, 2004

    I just got off the phone with my step-mother and boy are my arms tired. She way trying to do a mail merge. I told her about a month ago put data into an Excel spreadsheet in a data-like format (and I sent her an example spreadsheet to start from). Then, after entering the data into her spreadsheet, I recommended to her that she choose Mail Merge from the Tools menu in Word and she'd be home free.

    Of course, she wasn't. For example, after choosing her Excel spreadsheet, she was asked if she wanted to use first name, Sheet1$, Sheet2$ or Sheet3$ as her data. Having zero idea what SheetN$ was, she chose something vaguely human-sounding, which was exactly what she didn't want, then was frustrated when her data didn't come up. Later, after going away to buy hundreds of dollars worth of books (none of them telling her how to do Mail Merge using words that she could understand, btw), she opened up her document and was presented with a dialog box asking whether it was OK to run an SQL statement. "What's SQL?" she asked. "Nothing that any normal human should ever have to see," I replied, growing more embarrassed about the state of the output of my industry by the minute.

    Later, when we got the data working with the merge (Remote Assistance, even over a slow phone line to Fargo, ND, works *very* well, once I figured out how to take control of her computer [answer: Take Control in the upper left]), she turned her attention to reformatting her letter. For example, she'd pasted some text from the web, which, by default, left this weird web formatting instead of making it look like the rest of her letter, so the styles were very different. Luckily, selecting the text and turning off the bold was enough, otherwise I'd have either had to reformat her entire letter or talk her through doing it. And how did I tell her to turn off the bold? By selecting the text and pressing Ctrl+B? Why did I tell her that? Because Word had taken the Bold toolbar icon off the toolbar and I couldn't imagine describing to her what the little chevron was for so that she could get it back.

    I've listed only a small percentage of issues I worked through with her, but lest you think otherwise, my step-mom is no idiot. She's a nurse anesthetist, so has to keep tons of details in her head all day long or people die. Also, she's trained her dogs to win first place obstacle courses in competitions around the country, one of whom was said to be untrainable. But when it came to Mail Merge, she worked for three weekends straight before giving up and calling me. It's clear to me that for anything but the simplest of tasks that computers are not even close to ready for normal humans. On behalf of the software engineers everywhere, I'd like to apologize to Charlene (my step-mom) and the rest of the normal humans everything who are merely trying to make computers actually work. Hopefully Longhorn will fix this problem, but until then, I recommended that she return her computer to the manufacturer and get herself a Nintendo. After working through this with her for over an hour, I was only half kidding.

    Discuss

    What Would You Save If Your House Was On Fire?

    Saturday, January 31st, 2004

    On a recent thread on my favorite mailing list ever, Jon Kale answers the question "what would you save if your house was on fire," which triggered my own thoughts along this line.

    Assuming I've already made sure that the humans and the pets were out of the house, I'd make sure to grab my Omega X-33 (purchased during the bubble, of course), but since I go almost nowhere without it, it's not likely to be burned up w/o its owner.

    Also assuming I had a set of back-up CDs/DVDs for the last year in my safety deposit box (which I don't have right now... please excuse the pause while I purchase a DVD burner... OK, $155 got me a top-reviewed DVD+R/DVD+RW drive with 30 blank DVD+RW disks delivered), the thing I would most miss is my book collection. The computer books could be replaced on demand, but my collection of just-for-fun books has literally taken a lifetime to collect and cull down to just things that I really love (click on the picture to get a closer look).

    Often, when I want something comfortable to read, I'll scan the shelves 'til something pops out at me and re-read it. Also, when friends & family come to town, I often take them to Powell's City of Books and we play the "Top 5 Books of All Time" game, purchasing what they point out for me and writing their name in the book so that when I read it, I can talk about it with the recommender (man, I've gotten some wacky books that way...). Losing those books, especially the ones I haven't gotten to yet, would really hurt.

    On the other hand, because you never know when you're going to need to jam, my goal is to fit my entire set of positions on a memory hypercube (or whatever). But how do I back up the books when the atoms themselves are so satisfying? I mean, how can I recapture the feel of my leather-bound The Complete Frank Miller Batman, the back-pocket-worn The Silicon Mage, my copy of The Hobbit and The Lord of The Rings signed by my mother when I received my Master's Degree because she read them to me when I was 10 or the ancient copy of The Complete Sherlock Holmes given to me by my father and to him by his father?

    But even if I wanted a lossy digital backup of my books, how do I do it? I mean, I can scan all of my books and graphic novels, but only by destroying them. Why haven't books, which are produced in digital form, made the transition to electronic availability? Are we waiting for the Tablet PC to get to a point of ubiquity?

    So, in summary:

    • How do I back up my favorite atoms?
    • What would you save if your house was on fire (after humans and pets)?

    Discuss

    Betting on Longhorn-Only?

    Friday, January 30th, 2004

    In response to my post yesterday (When In Doubt, Ignore Longhorn), Shaun asked whether he should be targeting Longhorn-only right now:

    [ed: the following has been edited to remove identifying remarks at Shaun's request]

    Thanks for all the great posts and community participation over the past year. Your recent 'Ignore Longhorn' post alarmed me a bit. I hope that was not born from some aspect of it being pushed past 2006.

    Anyway, I know you are busy, so I will get to the point. We are mid-sized, established s/w company, and a Microsoft shop to the core (SQL Server, Analysis Services, VB, we embed VBA etc...). I am facing a huge decision regarding building our next gen app architecture. We need to ship in 1H 2006, and (IMO) we need to target rich and reach, so Longhorn is on my list of possible directions along with some ASP.NET 2.0 / ClickOnce combination.

    I am enjoying working with Longhorn (XAML in particular), but I'm having a hard time shaking the feeling that I am taking too much of a gamble if I go Longhorn-Only, but some of the aspects are just so compelling. On the other hand, I'd hate to make a huge 2-3 year dev investment in ASP.NET only to ship something in 2006 that is not revolutionary/differentiated. I firmly believe our existing 3 million lines of solid COM code has plenty of life in it too.

    Any insight or advice you might have would be greatly appreciated. I know it is probably difficult without understanding our company or market, but maybe some general advice to someone who is targeting a 2006 release. I guess my other worry surrounds the Longhorn adoption rate, but obviously none of us can predict that!

    Here was my answer:

    Shaun, if you think that Longhorn is going to help you build a differentiated product that'll help you be more successful, then great! That's why we're building it.

    On the other hand, if I were you, I wouldn't put all my money into a single investment. Instead, I'd use some diversification strategies like you would with your financial portfolio. At this point, the ship date of Longhorn, along with the list of features it will support when it ships, is merely speculative. I won't put more than 10% of my available investment time/money/staff into it, leaving the rest of my portfolio for getting the most I can from my existing and/or near future technologies.

    Specifically, you ask about ASP.NET 2.0 and Windows Forms/ClickOnce. Both of those technologies rock. ASP.NET is going to be the way to build web sites and services for the next decade at least, even after Longhorn's been out for years, since it has the reach across our existing OSes and competing OSes. Plus, ASP.NET 2.0 has a dizzying list of new features that people will spend years just taking full advantage of. For reach, you can't make a better investment than ASP.NET.

    For rich, on the other hand, Windows Forms + ClickOnce is a killer combo. The updated Windows Forms in Whidbey along provides some amazing new capabilities, not the least of which is the new GridView, which you can read about in Michael's new Wonders of Windows Forms piece. Also, look for a "What's New in Whidbey Windows Forms" piece in MSDN Magazine RSN. ClickOnce (which you can learn more about in Duncan's ClickOnce piece and in Jamie's ClickOnce talk) is the way to deploy rich clients in Whidbey and in Longhorn, so digging into that technology is a very good idea.

    As time goes on and Longhorn becomes a more solid development investment, you should put more of your portfolio into it. If you've got plenty of time/money/staff, than 10% now could mean an entire pilot project in Longhorn, which would be a good thing. But if you've got limited amounts of time/money/staff that you really need to yield a dividend now, Longhorn is dangerous for you and should only be something you dabble with at this point.

    For you specifically, a mid-sized company, you should carve off a chunk of your dev. staff to build a pilot in Longhorn. This lets you dabble while the rest of your staff is busy with existing and near future technologies. And as you dabble and notice things that don't work at all as you expect or need, let us know! Operators are standing by to take your calls! We're at a stage in our development process where we're able to give much more attention to the fundamentals than we will be at beta, so the 10% you put into Longhorn now could yield large dividends in the future.

    And as to your follow up comment, I'm happy that you enjoyed my response, but I'm pretty sure an autograph from Sting would be cooler. : )

    When In Doubt, Ignore Longhorn

    Thursday, January 29th, 2004

    A guy walks into an exotic car dealer and asks the salesman the price of the fancy new Ferrari in the corner. The salesman looks at him with a sad look on his face, shakes his head and says, "I'm afraid, sir, that if you have to ask, you won't be able to afford it."

    If you're wondering whether you should be paying attention to the information on Longhorn that has appeared on the web and in the news lately, then you shouldn't be. Longhorn RTM is years away. This is the most lead time we've given on any Windows operating system ever. The reason we did it was so that we could get super early adopters to give us meaningful feedback while we still had enough of the development cycle left to make meaningful changes. If you're not a super early adopter, than Longhorn is just going to be noise that you should ignore 'til the beta hits.

    For day-to-day development, you should pay attention to .NET 1.1 news sources. For the near future, you'll want to listen for Whidbey, the next version of the .NET Framework, which should work on all supported OSes when it ships. Here are a list of my favorite news sources for current information and near future information:

    .NET Framework 1.x Information Sources:

    • MSDN: The vast majority of existing and new information you'll find on MSDN is on currently shipping technologies. My Developer Center brethren post tons of new stuff every month all about helping you be successful today. Also, one part of the Longhorn Developer Center that you should check out is the Preparing for Longhorn section, where I keep resources that you'll need to know about today so that you can keep Longhorn in mind for tomorrow (or the day after tomorrow : ).
    • MSDN Magazine: MSDN Magazine does a fabulous job of helping folks take advantage of .NET 1.x and have recently been doing articles on Whidbey and Yukon.
    • MSDN Columns: If you haven't seen the columns that MSDN hosts online, you're missing a ton of great stuff from experts in the field. Besides the Longhorn columns (which you should ignore if you're in doubt!), my personal favorite is Wonders of Windows Forms, which has also been focused on taking the best advantage of Windows Forms and where Michael Weinhardt has just started with a series of Whidbey Windows Forms topics that'll make you drool.
    • GotDotNet: This site is host to a raft of content and tools and code samples from the .NET product teams along with active web forums.
    • CodeProject.com: CodeProject is my favorite user-contributions site and has tons of new source code samples and articles all the time about all manner of existing Microsoft technologies.
    • DotNet Newsgroups: The newsgroups are a hotbed of information on current technologies and are staffed by a large number of Microsoft employees to answer your questions.
    • International .NET Association (INETA): Don't just sit around and code by yourself, find a user group near you!
    • DevelopMentor mailing lists: The .NET mailing list hosted at DevelopMentor launched a development culture. Their mailing lists are still tops in my book.
    • .NET 247: I can't tell you how often my Google searches on Microsoft-related technologies yields an answer on this site.
    • Most Microsoft bloggers: Sure, Box, Anderson and Scoble hog the limelight, but some of my favorite bloggers concentrate on today's technologies. Don't miss Adam, Chris, Duncan, Dino, Kent or Raymond.
    • Whidbey Series on MSDN TV: If you want some info on the not-too-distant future, Erica Wiechers's series of Whidbey topics on MSDN TV is a great place to start.
    • Whidbey/Yukon PDC talks: Contrary to popular belief, most of the talks at the PDC were not Longhorn-related and it's not too late to catch the videos or download the slides if you weren't able to catch them all.
    • Scott Guthrie's Blog: For juicy bits of ASP.NET 2.0 information, you can't beat Scott Guthrie's blog.
    • theServerSide.NET: I haven't spent much time on this site yet, but Richard Burte, an MS PM, says he likes it well enough to add it to this list.
    • What did I miss?

    That's not to say that Microsoft is going to stop talking about Longhorn in the WinFX newsgroups, on the Longhorn Developer Center and in blogs of all kinds. We do this so that those folks that can think about the distant future today have a chance to make their voices heard at a time when we can most take advantage of what they're saying.

    However, there continues to be more information than any human can consume on current Microsoft technologies, so don't be alarmed when you see something go by with Longhorn in the title; just ignore it until you think that Longhorn can help make your business more successful. That's why we're building it after all. : )

    Surprised by Microsoft's Openness

    Friday, January 9th, 2004

    I get a lot of emails from folks surprised about how open Microsoft is being lately, mostly due to all of the blogging we've been doing lately (some of us started long before we ever became employees). However, even I was surprised in an internal blogging meeting today filled with a bunch of MS bloggers. During the meeting, we talked about a bunch of the benefits to MS and to our customers. Sara talked about how blogs are driving more traffic to MSDN than our own headlines. Robert described his "green, yellow, red" scale for determining whether to blog about something (believe it or not, he does decide not to sometimes : ).

    And then Adam Sohn from marketing talked about the need to police ourselves, describing some of the downsides in regards to blowing some group's launch plans or unconstructively criticizing another group. He preached caution when approaching the line between what was good for the customer and what was good for Microsoft. After listening to what I began to interpret as a message of self-censorship, I asked Adam a warm up, "Isn't it true that a lot of the stuff close to the 'line' is what our customers find most valuable?" He agreed that it was. And then I asked Adam my real question, "So, when we get close to that line, do we err on the side of our customer or ourselves?"

    Now, you have to remember that I've been a contributing member of the Windows development community for a lot of years. I've seen how aggressive Microsoft is in everything it does to always be on top. So when I asked on what side of the line I should come down, I fully expected to be told to keep the shareholders in mind.

    Of course, you know what his answer was or this story wouldn't have made it into my blog until after my tenure at MS was complete (or just before : ). He said, without hesitation, "Err on the side of the customer."

    That blew me away. Of course, I've been doing just that since before I became an MS employee and Robert rides the ragged edge all day long, but it was *very* nice to hear that guy with the PR and legal battle scars tell me to keep the customer first and foremost in my mind.

    Thanks, Adam. You've confirmed my decision to work at Microsoft.

    On Genghis, WinForms and How to Move Towards Avalon

    Saturday, January 3rd, 2004

    Inspired by my pending interview of Don Box, Paolo Severini sent along an interview for me.

    Paul: Being a faithful reader of your books, articles and of your blog, I'd like to ask you a few questions about LH, Avalon and the future of WinForms. Before all, let me say that I'm really fascinated by Longhorn, and especially by Avalon. I installed the PDC stuff as soon as I received it through my MSDN subscription and I've begun exploring it with "pure geek" enthusiasm. Everything is extremely interesting, but I'm now not sure what to do with it.

    Chris: I know what you mean, Paul. I'm going through that myself. Suddenly having so many fewer barriers tends to throw off the engineer in me. I'm working through it by begging the Longhorn User Experience team for guidance, learning Adobe Illustrator, reading graphic design books and trying to open my mind to the graphic designer inside us all (I hope : ).

    Paul: Paraphrasing one of the questions you proposed to Don Box: what should a WinForms programmer *really* do today to prepare for Avalon?

    Chris: If you want to write code today that'll work well on Longhorn tomorrow, write WinForms today. WinForms in Whidbey gets tons more features and I expect they'll be some cool new Longhorn-specific stuff when the time is right. If, when you're preparing a Longhorn version of your application, you'd like to host Avalon controls from your WinForms app or even build Avalon apps that host your WinForms controls, you'll be able to do that in Longhorn via WinForms/Avalon interop.

    For maximum flexibility in the code you write now, be very thorough about separating the data from the view of the data so that you can write a 100% Avalon front end to replace your WinForms front end if such is your need. Likewise, be very thorough about separating the data from the storage of the data is that you can take advantage of WinFS.

    Paul: I'm very grateful to MS for having disclosed their future technologies so soon, and more generally, to have become so "opened" to outsider's eyes, with so many devs and PMs now blogging about their work.

    Chris: Me, too. Without this openness, I'd get into lots more trouble. : )

    Paul: But I somehow also think that maybe LH was presented a bit too soon. Since it's not planned to be released before 2006, chances are that the shipped version could be significantly different. (Will it? Is it already? Can you write anything about that? :-).

    Chris: I used to think that we were unveiling Longhorn too soon, too. However, the later in the development process we get it out to reviewers, the fewer major changes we'll be able to make based of your feedback. What that means, of course, is that some major things are going to change between now and release, but those changes will be based on decisions that include feedback from you. The downside is that you'll have to relearn some of the things you learn with these bits. Hopefully, the upside is that most of what you have to unlearn will be replaced with something significantly better.

    Paul: Furthermore, even when the new presentation subsystem will ship, it seems like it won't be easy to write code that supports both the new and the old platforms, being they so different, and that could slow down its widespread acceptance even more. So I'm afraid that we'll all have a difficult time writing user interfaces, having to decide whether to take advantage of the new features or simply stay with the old portable libraries. After all, there are today still (too many) people running Windows 9x. And Windows XP is such a great OS that won't universally be replaced so soon.

    Chris: I've already mentioned how well WinForms will work under Longhorn, so I think I've answered part of your question. However, you're asking something deeper here, i.e. when do I give up the old "way" that has more ubiquitous support for the new "way?" In this case, you're talking about .NET and Longhorn, but you could as easily be talking about DOS and Windows or Win32 and .NET. This is the eternal struggle and the reason that we need software engineers in the first place. As with all such questions, the answer is "it depends."

    My general purpose answer is to always pick the newest thing that meets my requirements. The newer the technology you pick, the longer the shelf life. Can I build cool, scalable apps that take advantage of the high resolution monitors and GPUs of tomorrow in DOS? Absolutely. Do I want to? Hell no. Can I do it in WinForms? Yes, although it'll still be harder than doing it on Avalon. Will I increase my available market by targeting DOS today? The answer used to be "yes," but for a while now it's been "no." What about WinForms? The answer is definitely "yes" today and will be for a while yet, even after Longhorn ships.

    The answer to the question of when to adopt new technology has too many variables for me to provide any general advice better than "as soon as possible." Of course, Microsoft wants the answer to that question to be "sooner rather than later," and we're working to make Longhorn kick-ass for developers, business users and consumers so that ubiquity is taken out of the equation as soon as possible. Please use all channels of communication you have into the company to help us make sure we're doing that. The WinFX newsgroups are one good place for such feedback. They are heavily monitored by all of the WinFX teams and the Longhorn User Experience (Aero) Team.

    Paul: I found out that the PDC build of Avalon doesn't really work in kernel mode but simply uses two (unmanaged) DLLs, milcore and milrender built upon the old GDI APIs (to the point that it is actually possible to run Avalon on XP). Of course, that's bound to change, as Chris Anderson wrote, with the new video driver model and when the desktop composition stuff will get turned on. But wouldn't it be nice if a subset of Avalon ran on XP? After all, not every app will take advantage of its more advanced features.

    Chris: Before I answer this question, I just wanted to point out that GDI is not part of the Avalon rendering path. Instead, Avalon is built on DirectX, which is built directly on the drivers. GDI is still supported, of course, but it's a parallel rending path to Avalon's.

    The answer to the core question, i.e. why not ship Avalon on XP, is one of resources. Chris Anderson once told me that something like a man millennia has gone into the development of Avalon thus far. Even if Chris was exaggerating for effect, that's still one hell of a lot of work. That work has gone into building an architecture that allows application developers to take advantage of features present all the way down to the hardware level, including changes at every point in the presentation stack. What kind of work do you think it would take to make a subset of that available under Windows XP? Or Windows 2000? Or Windows 98? What kind of work do you think it would take to support those features on those down-level operating systems in their subsetted states? If we're looking at a release years into the future already, how many more years are we willing to wait to release Avalon in a form that works in a subsetted form on those OSes? And what will we ship to our customers expected a new OS in the meantime?

    It may be that you could come up with answers that you love to these questions. Would our other customers answer them the same way? Would our shareholders answer them the same way? Would your answers best position us against our competitors?

    Even if you got a subset of Avalon that works across .NET platforms today, would it really enable you to be more successful at your business or is it an engineering "gosh that'd be neat?"

    I know that our product teams really listen to our customers these days, so if you've got specific scenarios that you need enabled to be successful, please let them know.

    Paul: Furthermore, if XAML is, in the end, only a way to glue together a graph of CLR objects, why don't use it also to build WinForms UI? Both these options would make the transition much easier.

    Now that's a question I can provide a more satisfactory answer to, I think (sorry about that last answer : ). In the Longhorn PDC bits today, you can generate WinForms apps using XAML for the very reason you state. Likewise, if you'd like to try a subset of XAML in today's version of the .NET Framework, there are not one, but two 3rd parties providing early access to projects to allow this to happen. Given the amount of work that has gone into, and will go into, getting Avalon out the door, I doubt very much that their versions of XAML will be full-featured, but it may help ease the transition, as you say.

    Paul: That brings me to ask you about the future of WinForms (about which I'm now reading your book and really enjoying it). In the near future I will surely have to write WinForms code. But is it still worthwhile to spend time studying and trying to improve it? (I personally think so). Or should I rather concentrate my interest learning everything about the new LH technologies? So I'm back on the question about how to prepare for Avalon...

    Chris: I'd say that it absolutely makes sense to continue to write WinForms applications for years to come. Not only in WinForms a great platform for client applications today, but in Whidbey, it about doubles in size and capability. Plus, WinForms applications will continue to work great under Longhorn and will form the core of an application that needs to take advantage of Longhorn features under Longhorn but continue to work on the rest of the .NET platform. Unless you are planning to target only Longhorn, WinForms is absolutely where you should be spending your client development effort today and for years to come.

    Paul: Speaking of WinForms, one of the things I've never liked is the absence of windowless controls. It has been said that windowed and windowless controls are difficult to make live together, and that's true. But windowless controls are sometimes very useful (and cool! just think to the Windows Media Player UI). I found in your Genghis page that the "Windowless control architecture" feature is still "opened" and I'd like to try to work on it. (In the past, I wrote an ActiveX control container that supported windowless controls, so I wouldn't start from zero).

    Chris: Windowless controls were meant mostly as an optimization when creating thousands of Window handles brought the platform to its knees. Some folks also used windowless controls as a good way to fake non-rectangular controls. In modern implementations of User32, neither is much of an issue, so windowless controls provide a service that is no longer required in most cases. In the specialized cases where it is still necessary, I find that building an aggregate control that does the drawing of multiple controls that you would have made windowless in the past solves most of my needs in this area, although your mileage may vary. Given that Genghis has most of the rest of the features that I wanted for it, but no windowless control architecture, I'd say that folks seem to agree with me that windowless controls are no longer as important as they once were.

    Paul: But I also noticed that the Genghis project has been still for a few months, so I'm now wondering if it is still alive and if my project still makes sense now that Avalon is on its way. May you give me an advice?

    Chris: I was waiting for a wizard that would generate MDI, SDI and multi-SDI applications before shipping the next drop of Genghis, but there are enough new things and fixes that we should have another version of Genghis out in a week or so. If you or anyone would like to build the wizard (or just send Scott Densmore email begging him to finish the one he already started and has promised to me several times) that'd be great.

    Thanks for your wonderful job and for the time you dedicated to this mail. I just hope my English was understandable... :-)

    Best regards from Italy,
    Have a wonderful new year!
    --Paolo Severini

    Lending a Helping Hand

    Tuesday, December 23, 2003

    I know this sounds like spam, but it's not -- it's from my Uncle Mark, who's also my godfather and the nicest man I've even known:

    Chris, I'm writing you to ask your help. My brother Tom was gravely ill. Tom is 55 years old, married with two grown sons. He needed both a liver and a kidney transplant. He just received his transplants. It was by the grace of God just in time as he was within 2 to 3 days of death. He is doing well with no signs of rejection and just some minor complications. Unfortunately, he is nearly bankrupt from all his medical bills. Tom's life has been marked by several challenges, many overcome through hard work and determination. He is a man of immense spirit and we all love him dearly. This is a challenge he can't face alone. As you can imagine, our family is very concerned. We pray a lot. We have also undertaken a benefit and raffles for him to help him with his expenses. Right now we're just trying to help him pay his mortgage and put food on his table. He hasn't been able to work for three months. He also faces a tremendous bill from the transplant that his health insurance won't pay.

    There are five courses of action I'd like you to consider. First of course is I'd appreciate your prayers for my brother Tom that he continue to recover his health and his finances. The next four things I am asking for is your support of our raffles and benefit.

    I would like you to consider purchasing a ticket for what we call the "Big Money Raffle". There will be a limit of 110 tickets sold. First prize is $2000. Second prize is $1250. Third prize is $750. There will be an additional ten $100 winners. Odds of winning some prize are 13 in 110. 3 in 110 chance of bettering your bet. 1 in 110 of winning the top prize. Tickets cost $135 apiece. Much better odds than the lottery. Drawing 1/11/04.

    Also available are Quilt tickets at $1 apiece. My sister made the Queen size quilt. Value is somewhere between $1000 and $1500. Drawing 1/11/04.

    The third thing I'd like you to consider is if you know anyone among your connections in the computer world who might also like the opportunity to purchase "Big Money" and "Quilt" raffle tickets. I know you know a lot of people and some of them might be generous of spirit and/or gamblers. I think this time of year people yearn to be of help and service but aren't often sure what they can do. This is one such opportunity.

    The fourth thing I'd like you to consider is helping with the benefit dinner. It will be January 11th. There will be a silent auction. I thought with your connections at Microsoft you might be able to get them to donate something for the silent auction like some software or ?. Mr. Gates has such a wonderful legacy of philanthropy and I'm hoping that may reach down the organization for individuals in need.

    Thank you Chris for your consideration. If all you can offer is your prayers I will understand and greatly appreciate them. If you or anyone you pass this on to wish to purchase tickets, checks can be made out to "TOM NEEDHAM LIVER TRANSPLANT FUND". Anyone wishing more details can contact me, Mark Needham at 952-226-1769 or e-mail me at emkayen@aol.com. I will be happy to fill out the tickets and return the stubs to them. The information needed is name, address & phone number for both the Big Money and Quilt raffles. The Minnesota lawful gambling exempt permit # is X-34753-04-001.

    While I don't know my uncle's brother (his part of the family never really mixed with mine for some reason), because it's important to my uncle, I'll be purchasing one of each of the two kinds of raffle tickets, publicizing my uncle's plea on my web site, investigating Microsoft's matching for charity and, of course, sending my prayers. If any of you is interested in participating in the raffles, let Mark know directly. If you wanted to publicize this on your own web sites or donate something for the silent auction, let Mark know about that, too. Of course, all prayers are warming accepted.

    Thank you very much and have a Merry Christmas and a Happy New Year.

    Learning to Learn, Part II

    Sunday, November 30, 2003

    Tony R. Kuphaldt, an instructor at Bellingham Technical College in Washington recently emailed me that my Learning to Learn piece spoke to him and pointed me to his web site where he provides a wonderful look at his own experiences in self-teaching. In this paper, Tony describes his insights, starting with an amazing look into my own previous field of employ:

    "Industry training, at least in its popular form, is roughly based on the model of a fire hydrant: sit in front of it, open the valve, and take a big drink. Due to time limitations, trainers present information at a rapid pace, with participants retaining only a fraction of what they see and hear. What knowledge they do gain seldom passes on to co-workers after the training session, and is forgotten almost as rapidly as it is presented, necessitating continual re-training. ... [Students] often leave with the impression of the instructor being something of a genius for being able to present so much information so quickly, and instilling within their own minds a sense of inferiority for not grasping all of it at the delivered pace."
    Further, Tony describes the technique I use to really learn something:
    "What did I do to learn? Simple: I would challenge my existing knowledge of a subject by trying to apply it to real-world conditions and/or thought experiments. If I didn't know enough about a topic to successfully apply it to a realistic problem, I would research and study until I did. If ever I was completely baffled by a problem, I could determine my own conceptual weaknesses by incrementally simplifying the problem until I could solve it. Whatever complexity I eliminated from the problem that enabled me to solve it was where my understanding was weak. � Once I knew what I didn't know, I not only knew where to focus my study efforts, but I also felt more motivated to study because I could perceive my own needs."
    Tony characterizes his (and my) self-teaching technique as an internal feedback loop, where the student knows what he doesn't know. This is as opposed to an external feedback loop in an instructional setting, where the instructor knows what the student doesn't know, but the feedback loop is broken between the student and the instructor.

    And as if that weren't enough, Tony takes his goals on the road, as it were, testing a self-teaching-based curriculum on his students and reporting on his results. I find his work especially interesting not because I feel the need to teach the world to teach themselves; I'm perfectly happy to encourage folks to learn to learn, but to have them choose other techniques. However, I do feel very strongly that the Sells brothers learn to learn. I can't imagine sending them out into the world without a firm grasp of the ability to teach themselves. I don't know how to do that, though, unless I start home schooling them. That wouldn't be out of the question except for this unhealthy addiction I have to a steady income stream...

    The Wonder that is XAML's Extended Attribute Syntax

    Saturday, November 29, 2003

    I've been playing with GridPanel today and really like how elegant it is. If I say the following:

    <GridPanel>
      <SimpleText>Testing</SimpleText>
      <SimpleText>1</SimpleText>
      <SimpleText>2</SimpleText>
      <SimpleText>3</SimpleText>
    </GridPanel>

    I get the equivalent of an HTML table with four rows with each SimpleText element forming a cell like so (augmented with Border elements not shown above to accentuate the cells):

    If I want to split the data into columns, I can do that using the Columns attribute:

    <GridPanel Columns="2">
      <SimpleText>Testing</SimpleText>
      <SimpleText>1</SimpleText>
      <SimpleText>2</SimpleText>
      <SimpleText>3</SimpleText>
    </GridPanel>

    Which gives me two rows of two columns each:

    That's all nice and simple, but still flexible. For example, if I want to set the Testing string to cover two columns, I can give it an ID in the XAML and call the GridPanel.SetColumnSpan static method in code, e.g. when the Window loads:

    <!-- xaml -->
    <Window ... Loaded="window1_Loaded">
      <GridPanel Columns="2">
        <SimpleText ID="testingSimpleText">Testing</SimpleText>
        <SimpleText>1</SimpleText>
        <SimpleText>2</SimpleText>
        <SimpleText>3</SimpleText>
      </GridPanel>
    </Window>
    // C#
    void window1_Loaded(...) {
      GridPanel.SetColumnSpan(testingSimpleText, 2);
    }

    This code yields 3 rows arranged as follows:

    This is all fine and makes you appreciate the elegance of the GridPanel. However, that's not what inspired me to write this entry.

    Remember that the SimpleText element serves as a cell in the GridPanel. Even better, the SimpleText element doesn't know it's serving as a cell in a GridPanel. The architecture of Avalon is loosely-couple so that all of the elements don't need to have intimate knowledge of each other. This loose coupling is really great for future elements that some developer wants to host in a GridPanel or that want to host SimpleText elements. Still, I'd like to be able to set GridPanel-related properties for each "cell" on the cell element itself, even if the cell element doesn't know it's a child of a GridPanel. And that's what the extended attribute syntax in XAML lets me do. Instead of writing the code, I can just do this:

    <GridPanel Columns="2">
      <SimpleText GridPanel.ColumnSpan="2">Testing</SimpleText>
      <SimpleText>1</SimpleText>
      <SimpleText>2</SimpleText>
      <SimpleText>3</SimpleText>
    </GridPanel>

    This dotted attribute syntax allows me to set a GridPanel setting for the SimpleText element w/o any knowledge from the GridPanel of the SimpleText or vice versa. That means that if I define the FooBar element tomorrow, I can set it's GridPanel.ColumnSpan on it when it's used inside a GridPanel w/o extending GridPanel. This also means that if FooBar has a Quux per-child property, I can set the FooBar.Quux attribute of the SimpleText element w/o extending SimpleText. Nice!

    BTW, if you'd like to see the code that provides the GridPanel in "outline mode" as above, it looks like this:

    <Border Background="black" Width="100%" Height="100%">
      <GridPanel Columns="2">
        <Border Background="white" GridPanel.ColumnSpan="2">
          <SimpleText >Testing</SimpleText>
        </Border>
        <Border Background="white">
          <SimpleText>1</SimpleText>
        </Border>
        <Border Background="white">
          <SimpleText>2</SimpleText>
        </Border>
        <Border Background="white">
          <SimpleText>3</SimpleText>
        </Border>
      </GridPanel>
    </Border>

    Notice that the GridPanel.ColumnSpan is on the Border element, not the SimpleText element. That's because it's the Border that's the cell of the GridPanel, not the SimpleText.

    I don't know UIs, but I know what I like...

    Monday, November 24, 2003

    The user in me sees Longhorn and dreams of software without limits. The engineer in me sees Longhorn and is scared of software without limits. An engineer's days are defined by requirements and restrictions. Those restrictions come not only from the capabilities of the tools and technologies being bolted together, but also accepted practice. For years, I've been comfortable designing "rich" client applications because a) my tools and technologies haven't let me do much that was really "rich" and b) because "rich" was pre-defined by existing applications.

    In fact, when I started programming Windows 3.1, I adopted a single 3-step UI design process:

    1. Figure out the the requirements of the particular UI doodad I needed
    2. Find my favorite example of it in Visual Studio, Word or Outlook
    3. Make User/MFC/WTL/WinForms do that

    It doesn't take much to design an application that looks like this:

    or even one that looks like this:

    when the process is merely aping existing apps. I was even encouraged to use this kind of UI design by books with color pictures from well respected authors:

    User Interface Design for Programmers

    When the web came along, things were scary because all the guidelines were gone. However, at first the limitations were strict, so I didn't have any trouble building sites that looked like this:

    but when a few years later, the limitations faded away and I was expected to conceive of and implement stuff like this:

    I didn't have a clue. Luckily, the web "way" settled down over the years so that we figured out basically how to design web sites:

    Book cover: Don't Make Me Think!

    Plus, limitations took hold as we realized that you could build pretty much anything you wanted unless you wanted it to work on someone's machine besides yours, which turned the screws down pretty tightly.

    Still, while the emerging conventions helped me figure out what I wanted my own web site to look like in general, I had to *pay* for help from a otherly-skilled professional before I could get the specifics:

    This is where it got scary until I had the one application designed for which I would ever need a designer. With my web site out of the way, it was smooth sailing.

    That is, until Longhorn and Avalon came along.

    Avalon drops the bottom out of the limitations and the guidelines again, leaving guys like me in a lurch. Oh sure, I've done pretty much everything there is to do in this industry, from coder to President, from docs to QA, from project management to *shudder* marketing. However, what I haven't done and always hoped to avoid was design the graphics that go along with an application. Those were always things that I could hire done, most often as a deductible expense.

    But now what do I do? MS doesn't provide MSDN authors a "graphic artist" budget. We do have very talented graphic artists at MSDN, but what's my boss going to say when they're swamped doing graphics for my pet projects and not the public-facing web site?

    And standard bitmap graphic artifacts aren't enough; I need *vector* graphics. Even I can see that while this is fine:

    nobody is expanding sol.exe's main window to get more "green space":

    To solve problems like these, we need vector graphics that look good when they're scaled, which I understand is roughly 10x harder than bitmaps (which are already beyond me).

    But just the graphics aren't enough, either. MS is busy redesigning the Windows "user experience" to include the best of Windows and the web:

    Apps are supposed to behavior sensibly (which I can handle) *and* look cool (where do I learn to make *that* happen?!?).

    In fact, taking the next step from the budding UX guidelines, we seem to be heading into a place where if I want to build my own sol to fix the scaling, I'll be trying to fit a "menu system" on the front like the gaming guys do:

    and like so:

    In fact, I've heard tell that there's a special guy that designs these pre-game antics separately from the rest of the game just so folks think the game is cool as soon as it starts, long before you're actually playing it. How can I stand up to that kind of pressure? I was pretty damn happy with myself when I made blocks fall and stack:

    And while this is the only scalable game of its kind of which I know (I was ready for Avalon a while ago, apparently : ), it still has the standard un-cool "menu system" that Windows comes with out of the box.

    And there's no relief in sight! Avalon, by taking advantage of 3D hardware and displays that haven't even been invented yet, along with intrinsic support for every kind of media and animation that I'm familiar with, blows right by the limitations we've grown to know and love in Windows and web applications. Now we're into the world of game programmers, where if you can imagine it, you can do it.

    But where am I going to get the graphics for what I can imagine?

    How do I imagine a user experience when MS is literally still writing the book on it and they haven't shipped a Longhorn Visual Studio, Word *or* Outlook?

    Graphic/user experience designers of the world, please be gentle; the engineers are spooked and could stampede at any moment...

    Know where I can get some graphics/user experience designers cheap?

    My First Meeting with BillG's Technical Advisor

    Saturday, November 15, 2003

    In my continuing quest to take advantage of unique experiences at Microsoft for those that aren't able to, I spent an hour in a meeting with Bill Gates's Technical Advisor, Alexander Gounares, earlier this week. Among other things, Alex is responsible for getting answers when Bill asks questions like "Hey, what are we doing about adding air conditioning to Windows?"

    I've had meetings with senior execs at MS before and I always end up saying stuff that upsets them. This time, the guy was so nice, I just wanted to nod my head and do whatever he asked of me. In fact, the thing I volunteered to work on (a "vision" whitepaper exploring a new application of technology that's still under development) wasn't so much that he asked me to do it, but rather because he asked for a volunteer and made eye contact with me in such a heart-warming way that I couldn't say no. (Of course, my boss kicking me under the table didn't hurt, either... : )

    BTW, in case you wondered, while the Sr. VP I upset knew me from my blog, Alex didn't know me from Adam. : )

    For folks keeping track, in my six month career at MS, I gotten to do *lots* of cool stuff:

    • Launch the Longhorn Developer Center
    • Hang out back stage at the PDC, including preparing to act as Chris Anderson's demo understudy and helping ship one of MSDN's new features (annotations)
    • Write a Think Week paper for BillG and receive his comments back on it
    • Meet Anders Hejlsberg, Eric Gunnerson and Robert Hess
    • Have meetings with several execs, including one Group VP, one Sr. VP and BillG's TA
    • Crash a WinFX API review
    • Introduce MS to the joy of a DevCon
    • Help get my PUM blogging
    • Invent an extension to RSS that is getting fairly wide implementation, e.g. SharpReader, RssBandit and .Text.
    • Appear on The .NET Show
    • Get a few mentions in the press as an official MS employee (including one that my Mom saw that made her very proud : )
    • Keep up contact with the community as much as I'm able via email, mailing lists, newsgroups, articles, conference talks and appearances

    I list these not to brag, but to reflect on how many cool things there are to do at MS. I assume it's all down hill from here. : )

    Time For An Exciting Career In Electronics

    Monday, November 3, 2003

    Depending on how you look at it, what I'm best at in the whole world has either become completely unnecessary or incredibly easy. The skill that I spent most of the last 10 years learning was to look at a group of types, APIs, reference docs, headers, source code, etc., distill it down to a set of architectural intentions and then to weave a story through the whole thing to make sense of it for developers that weren't able to glean the intensions themselves (most often because they had real jobs). I call this exhaustive search for intention officially at an end. I'm no longer needed except as a gatherer for those not yet facile in RSS aggregators (which, luckily for me, is still a large number : ).

    Blogs like Chris's, Scott's and Raymond's go way beyond the "what" that docs and web sites and even mailing lists/newsgroups/web forums have typically stuck with and gone right into the "why." And not only that, but Chris is actually taking that next step on his blog. In the old days, before my favorite technology company became so damn open, if I wanted to comment on something, I had to painstakingly track down the right people at Microsoft, make friends with them (which first demanded that I learn social skills) and then convince them that someone outside of MS might actually have something intelligent and useful to say. This often involved years of stalking 'softies in mailing lists and conference halls and now Chris is letting anyone give him feedback to which he actually listens!

    What use a hack like me that doesn't invent something, but merely figures out how existing things work so that I can tell someone about it if the guy that invents it does that part, too?!? I wonder if there are slots left in the vocational technical school near my house...

    In Search of Expertise

    Monday, November 3, 2003

    I had an interesting insight while watching Episode II: Attack of the Clones (I had a hankering to see Yoda kick some butt, OK?!?). The definition of expert is someone that just does whatever it is they do; they don't think about it. Everyone else is just learning. What drove this home for me was when Anakin heard of his mother being taken and how everyone else had failed or died looking for her, Anakin started out after her without any planning whatsoever. *That's* an expert. Of course, he had The Force and the rest of us have to live with an average amount of midichlorian, but he'd done what I've seen other experts do, too: unconscious competence.

    The reason that this is such an insight for me is that for my entire life, I've always felt that there were special people in the world that just know what they're doing. These people worked in companies or were members of a profession and by their association with those organizations, I felt that they must be experts. I mean, how could someone be a member of professional for any length of time and not strive for mastery of the professional? It was watching Anakin that it finally sunk in that mere association is not enough; most organizations, no matter how high their standards, do not stop non-experts at the door. Experts are the ones inside the organizations that rise to the top, that stand out, that set examples for other members. Expertise is the thing that separates a moderately smart person studying up on a topic for a while from someone that really understands something down to their bones. This is what separates me catching up to my financial advisor after 6 months of study from a *real* money manager. That's what separates a new computer science graduate from me.

    That's not to say that I couldn't be better than some "real" money managers one day or that the new college grad couldn't be better then me on day one. What it does say, however, is that encountering a true expert is a rare thing. Because of that rarity, I believe that most reasonably intelligent people can, with study and practice, get good at practically anything that they set their mind to. This means that I can, with a reasonable amount of study and practice, check the work of my financial advisor or my accountant or a plumbing contractor and come up with things that they don't. I know that this is true because I've done it (not with the plumbing though, I'm practically clueless there : ). The amount of study I needed to catch up with my professional service provider doesn't make me an expert, of course, because it's highly unlikely that either of them is an expert.

    So, now that I've settled the question of whether membership in a profession makes one an expert (it doesn't), that leaves two questions:

    1. How do you recognize expertise? I know it when it occurs in something that I'm familiar with, e.g. computer goo, but what about in a discipline where I'm not versed?
    2. How do you obtain expertise? I've got this down to a science for programming APIs, but can these techniques be applied to other disciplines?

    Comments on my continued quest for expertise welcome.

    My First PDC as a Microsoftie

    Monday, November 3, 2003

    After all the preparation, planning and sheer work, it's a letdown for the PDC to actually be over. It was an amazing experience for me to be "back stage" at a PDC, the only conference I'd spent my own money on for years (although as a speaker, they let me in gratis this year : ).

    Things I Heard:

    As a Microsoft employee, my job is to listen and take feedback home. Here's what I heard:

    • Longhorn, Avalon/XAML, Indigo, WinFS, ClickOnce: good
    • Improvements in VS.NET and ASP.NET: good
    • Indigo and ClickOnce on existing versions of Windows: good
    • Avalon not available on existing versions of Windows: not so good
      (Avalon changes things all the way to the device driver level, so retrofitting it to existing versions of Windows is impractical)
    • Not being able to download the PDC Longhorn and VS.NET Whidbey bits: not so good
      (MSDN subscribers can request the CDs to be sent to them)
    • Developers that didn't go to the PDC and don't have MSDN subscriptions not getting PDC bits: not so good
      (the public beta in the summer of 2004 will open this up considerably)
    • The Longhorn Developer Center features and content: good
      (whew : )
    • Having all kinds of Microsofties at the PDC and on the newsgroups and mailing lists to answer questions and take feedback: good
    • Publicly contributed annotations on the Longhorn SDK content: good
    • Longhorn bits running under Virtual PC: good
    • Longhorn bits amazingly functional and stable: good
    • Longhorn bits not especially speedy: not so good
      (these are the earliest OS bits we've ever given to folks -- Longhorn will have years to improve in this and every other regard)
    • Availability of PDC network, both wired and wireless: not so good
      (don't know why this happened)
    • Stacking up outside the rooms of overflowing sessions: not so good
      (although MS attendees were very good about giving up their seats to paying customers)
    • Microsoft's commitment to pushing managed code so far into the OS: good
    • Lots of folks interested in contributing to the Longhorn developer community: good
      (if you're planning something, please let me know)

    Things I Got To Do:

    Also, as a first timer backstage at the PDC (and a long-time member of the Windows developer community), I got to do all kinds of fun things:

    • Give a pre-conference tutorial on WinForms with Rocky Lhotka, a fellow giant Minnesotan with whom I'd never before had a chance to work
    • Prepare Sunday night to do the keynote demo in Chris Anderson's place on Monday morning with Don Box and Jim Allchin in case Chris couldn't make it past the fires in time
    • Hang out on the PDC keynote stage late at night, soaking up the Chairman of the Board and Sr. VPs doing their last minute preparations (and inadvertently making career-limiting statements : )
    • Watch Don and Chris and Jim pull off an amazing all-code keynote that will go down in history as one of the PDC's best
    • Hang out at the Ask The Experts session, coding up repros and solutions to WinForms questions alongside Mark "Mr. WinForms" Boulter
    • Wandering the streets of downtown LA with Frank Redmond looking for Tim Ewald's surprise birthday party
    • Answer questions instead of ask them at the MSDN booth
    • Being interviewed by Jon Box of Sys-Con Radio and an old ATL student who blames me for his career choices
    • Spent a lot of time telling people about MSDN Developer Centers, where my friends at MSDN work very hard to pull information out of the vast MSDN library and organize it for particular audiences, e.g. C#, VB.NET, ASP.NET, Security, VS.NET, the .NET Framework, Architecture, etc.
    • Shake hands and sign autographs and have my picture taken with all kinds of old friends and ex-students and readers and conference attendees
    • Gush like a fan-boy at Tim O'Reilly
    • Watch a block full of cars all go backwards one night getting back into "first positions" (it was California, after all : )
    • See the 4' high by 20' long WinFS schema and realize just how much work the WinFS guys are actually doing to capture "Everyday Information"
    • Send out the official welcome to the WinFX newsgroups
    • Make tweaks to several potential keynote demos at the last possible moment
    • Do an interview with .NET Developer Journal that let me tell my side of all kinds of stories
    • Get all kinds of feedback from internal and external folks saying nice things about the project that has consumed me for the last 6 months: the Longhorn Developer Center
    • Go to a 1am show of The Metal Shop heavy metal "mock 'n' roll" band at the Viper Room on the strip in Hollywood with John Shewchuk and Matt Pietrek and screaming my voice raw to the lyrics
    • Meet Sunny Day live and in person
    • Hang out with Matt Pietrek, one of my personal heroes, along with Tim and Sarah and most of my closest friends (where was Craig?!?)
    • Shake my tail feathers to yet another amazing Band on the Runtime gig
    • Attend all kinds of technical sessions on the technologies of Longhorn so that I can continue to live the Longhorn life for those developers that aren't yet able to
    • Start the collection of items for a Longhorn Developer FAQ which I'll post when it reaches critical mass
    • Hang out with architects from two of the three main pillars of Longhorn (Don Box, Indigo and Chris Anderson, Avalon) at the The Kettle in Hermosa Beach
    • Share a room with the 19-year old .NET wunderkind, Ryan Dawson

    At this PDC, I definitely got to see how the sausage was made, but that still didn't take away from the deep, rich flavor. Recommend.

    How Does One Obtain "Inside" Information?

    Wednesday, October 15, 2003

    I got an email today from John Reilly today asking me a question I get from time to time:

    I got my signed copy of your book. It is a great read. You have information that a friend and I have been trying to dig out for weeks.

    Which leads me to our question. How do you find out all those details? They are not to be found in the MSDN documentation, as far as we can tell. Do you just experiment, like we do? We have been unable to find any .NET training that is much more than how to use the IDE. Alan and I crave detail, meat, the stuff of your book. Seriously, how does one obtain this seemingly inside information? We are personally and professionally motivated weenies.

    Now that I'm a Microsoft employee, I have access to not only the source for most of what I'm researching, but the architects and internal mailing lists populated by the developers on the project, so that really is "inside information." However, over the 8+ years that I was a contributing member of the Windows developer community, 99% of what I've done has not been based on inside information. So, before I had access to internal info, how did I figure stuff out if the docs don't answer my questions? I do the following, in order of decreasing frequency:

    • I experiment, writing hundreds of projects consisting of 10 lines of code or less to experiment with particular features
    • I read the source, even if that means reverse engineering it first (Reflector is fabulous for .NET code)
    • I search on the Microsoft-specific Google search page
    • I IM, email and call my friends who know more than I do (which is most of them : )
    • I ask questions on my favorite mailing lists and newsgroups
    • As a last resort, I ask my friends at MS. Buying a Microsoftie a beer at a conference, being smart in online forums and saying nice things about their technologies are all excellent ways to gain friends at MS

    What Is An RSS Feed?

    Thursday, October 9, 2003

    As a deadline nears and I spend an increasing amount of time avoiding the work I should be doing, I find a finance geek acquaintance of mine asking what an RSS feed is after I implored him to add one to his web site. This is a 20-year old that's owned stock since he was 11, read 12,000 company reports in 2002, earned 155% on his money is the last 11 months and recently been given his own $35M mutual fund to manage (becoming the youngest ever mutual fund manager). If this guy doesn't know what an RSS feed is, then I'm guessing at least some of my readers don't know either (yes, I'm talking to you, Mom). When he asked me what an RSS feed was, this is what I told him:

    An RSS feed is a thing of pure beauty. If you've ever been to a web site with an orange XML or RSS button, clicking it will yield a page that looks something like this:

    <?xml version="1.0" ?>
    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <channel>
    <title>Marquee de Sells: Chris's insight outlet</title>
    <link>http://www.sellsbrothers.com/</link>
    <description>Thoughts that Chris Sells has about whatever interests him that day</description>
    <dc:language>en-us</dc:language>
    <dc:rights>Copyright � 2002-2003, Chris Sells</dc:rights>
    <dc:creator>csells@sellsbrothers.com</dc:creator>
    <item>
    <title>The Wedding Toast</title>
    <dc:date>2003-10-10T04:17:02Z</dc:date>
    <guid isPermaLink="false">http://www.sellsbrothers.com/news/topic866</guid>
    <link>http://weblogs.asp.net/yosit/posts/31385.aspx</link>
    <dc:creator>Chris Sells</dc:creator>
    <slash:comments>0</slash:comments>
    <comments>http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=866</comments>
    <wfw:commentRss>http://www.sellsbrothers.com/news/commentRss.aspx?ixTopic=866</wfw:commentRss>
    <wfw:comment>http://www.sellsbrothers.com/news/commentApi.aspx?ixTopic=866</wfw:comment>
    <description>Don and I send out a video of a toast to a newly married couple. We get back their reactions via video. Not as nice as real-time, but I don't get overseas much, so still very cool. You gotta love the Internet!</description>
    </item>
    ...
    </channel>
    </rss>

    While RSS is fairly unreadable for normal humans, computers eat it up. For example, if you read the RSS feed from my site on a regular basis, whenever I make a new post, you'll see a new entry in the RSS feed. RSS feeds aren't useful for you, but when fed to an "RSS reader" program, you can keep up to date on literally hundreds of web sites without having to browse to them manually. The RSS reader will check each RSS feed to which you subscribe, letting you know when something new on a web site has happened and showing you what it is, giving you the option to follow up or ignore the new thing. Thousands of sites have RSS feeds, letting me keep up on a bunch of things:

    • My friends' writings
    • Global and financial news
    • People talking about topics of interest to me, like my favorite technologies or my latest book
    • My favorite comics strips (I need my daily Dilbert!)
    • The latest product and articles releases from Microsoft
    • Practically anything else I care about on a regular basis

    I keep up on all of this without ever visiting the web sites themselves them 'til something of interest catches my eye.

    There are a bunch of RSS readers in the world, but my favorite is SharpReader. If you install this program and start it up, SR will check all of the RSS feeds that you subscribe to on a regular basis in the background while you work, notifying you of something new by changing it's icon from blue to yellow. If you decide to install SharpReader, your next stop should be NewsIsFree.com, where you'll find all kinds of RSS feeds in any number of categories. After subscribing to a few of those, you'll want to stop by Tapestry, where you can find RSS feeds for tons of daily comic strips. If you want to get fancy, you can go to GoogleAlert, where you can subscribe to searches so that whenever Google finds something new on your search topic, your RSS reader will let you know.

    If you find the ability to track hundreds of web sites without surfing to each of them manually, RSS is for you. If you find my instructions intimidating, ask a computer friend to help you out (I'll be home for Christmas, Mom).

    My 9-Year Old Has a Cell Phone

    Friday, October 3, 2003

    Tonight is Friday night, which means the Sells family generally has pizza and a movie at home. However, since we've been through most of Blockbuster's catalog and the boys aren't quite old enough for most of my DVD collection (9 is a tad young for things like Fight Club...), we thought we'd take in the new Jack Black movie School of Rock. Kids-in-Mind.com gives it a 3.3.3, heavy on the poop jokes (which my sons like) and heavy on the irreverence (which I like), so it seemed like a winner. However, as most movies start between 7-7:30pm and I just noticed it was 6:30p but Melissa wasn't home with the boys, I started the calling. First was her cell, but I remember her telling me it was out of batteries. Then it was her sister's house, where she had been, but she had left for a friend's. Then the friend, but no answer. And then I remembered my son and his cell phone.

    My son is 9 years old. He's been into computers and gadgets of all kinds since before he was 3. A few months ago, he was digging around and found my old Nokia cell phone. It had some cool games, so he charged it up and started carrying it around with him. Then, he wanted minutes so he could make his own calls. So we finally found our way to the local AT&T wireless place (which wasn't really very local at all) and he spent his allowance money on pre-paid minutes ($10 for 20 minutes). After less than a week, he was down to 8 minutes left. He's most just calling his friends from our car (where I have my cell in my pocket w/o unlimited monthly minutes) or from our house (where we don't have long distance, but we do still have a land line), but it's his phone and his money and it gives him pleasure.

    It did, however, freak my wife out. "A 9-year old doesn't need a cell phone!" she'd say. I'd explain that it was his own money. "A 9-year old doesn't need a cell phone! Drug dealers have cell phones!" She and I both have our own cell phones and besides the occasional glass of wine, we don't even *use* drugs, let alone *sell* them. And while no amount of reasoning with her stopped her from being upset, she didn't say he couldn't have a cell phone, so now he does. That he keeps charged. And that he carries. And that he spends his own money on minutes for. And that I just called because he was with his mother:

    "Hello?" said my 9-year-old son on his very own cell phone, surprised but pleased to get a call.

    "Can I talk to your mother?"

    "Sure."

    "Hello. Sorry. My cell phone ran out of batteries," she said.

    "Aren't you glad that John has a cell phone?" I asked, not bothering to keep the smug out of my voice.

    "Hmphf," she said, not bothering to keep the annoyed out of hers.

    I think I may pay for his next batch of minutes just so I can keep calling her on his phone. : )

    Google is Scary Smart, or Just Scary...

    Saturday, September 13, 2003

    When I was a kid, the source of universal knowledge at home was the set of dusty encyclopedias that my Mom inherited from somewhere. Today, it's the Internet, via Google. That in itself makes Google the fulfillment of most sci-fi novels' description of the the-store-of-all-human knowledge (I wish the text of all books were up, but that'll happen in time...).

    Anyway, it didn't hit me just how comprehensive Google was 'til I typed in '"Joe Grammer" wife' yesterday (I was calling and wanted to be prepared to address his very nice wife by name in case she answered the phone). In 0.39 seconds, Google gave 45 results, the 3rd of which contained Joe's wife's name! It was Joe himself who'd mentioned his wife's name in a mailing list post but still, that's pretty damn scary...

    Respect for Marketing

    Friday, September 12, 2003

    Even in my short time at Microsoft so far, I've have already learned a *ton* from marketing. Of course, I'm working with lots of marketing folks as we get closer to the PDC. Because of my role, I have to worry about what's good for the developer. Marketing guys, on the other hand, have to balance that with what's good for the administrator, what's good for the user, what's good for the company, what's good for the shareholders and what's good for a bunch of other folks I don't even know about. And, they have to do it for all of the streams of information coming out of the company, which now includes lots of informal streams like newsgroups, message boards, user group talks and blogs. Anyone that can balance all of these folks and still get developers what they need has my unabashed respect.

    Let us pause on 9/11...

    Thursday, September 11, 2003

    My 8-year old was proud to remind me that today was the two-year anniversary of 9/11. I was surprised that he knew and grateful to his school for taking the time to discuss it. He then went on to tell me how cool he thought the explosions were, which left me less pleased with his school. When I told him about my own experiences that day and how many people died, it immediately took all of the "coolness" right out of the day for him.

    George Bullock, a colleague at MS who's birthday happens to fall on 9/11, has also had the "coolness" taken out of the day for him and sent around a mail that starts this way:

    "Let us pause on 9/11 to remember and honor the thousands killed, maimed, put out of work, and traumatized two years ago; also to honor the heroic, living and dead, who rose to the occasion on that terrible day. May God rest their souls and keep and protect their loved ones. May God also keep and protect our men and women serving here and abroad. Yes, there is much difference of opinion about what's happening in the world today; nevertheless, I think we all support the men and women of our armed forces and wish them a safe return home. They sacrifice a lot to serve their country."

    Personally, I try very hard not to let the terrorists get to me. Unfortunately, they have. Even time I get the anal probe treatment at the airport or a personal freedom is taken away by the Patriot Act or my sister-in-law is afraid to fly (and flat out refuses to fly on that day), they win. More subtly, ever time a US politician uses "terrorism" to push their own agenda, they also win. Please don't let them win. Have courage. Try to understand what it was that drove them to terrorism to attract our attention. Compare their lives to ours. But don't let them win. Don't let them take the right to the pursuit of happiness out of our lives.

    "Your enquiries frustrate the hell out of me"

    Friday, September 5, 2003

    I would classify my style of communication as "get to conflict sooner rather than later." A radio DJ once classified engineering abilities as a series of personality flaws that are accidentally useful in today's IT industry and, arguably, he's right. For most folks that have to work with me, it's generally hard at first, but eventually you either love me or hate me (and I continuously work to tip that percentage towards the former : ).

    However, it's the rare individual that can see past someone's personal communications style and still pull out the value. Alan Cooper is one such person. I was reading one of his books and was so lost that I called and blamed him and his parents. He straightened me out by letting politely me know that he book wasn't even trying to solve my problems and therefore it's not surprising that it didn't. Further, he ended his email like this:

    "PS. Your enquiries frustrate the hell out of me. That's why they are good and I want you to keep making them. If I growl at you, well, that's my problem. Not yours."

    I don't know if other people would appreciate Alan encouraging my behavior, but it's still cool to know that such tolerance exists in the world. : )

    Communication Is All

    Monday, September 1, 2003

    It's amazing to me the  number of problems that can be solved or avoided completely with communication. For example, the prevailing attitude of the day is that children should not be let out of an adult's sight, in spite of an all-time low in the history of violent crime. Towards that end, and since tomorrow is the first day of school, my oldest boy is currently testing the range of our walkie-talkies to see if he and his younger brother can walk to school. The reason? Because I can communicate with him to know that they got to school OK. I need that communication so that I can continue to be paranoid while still letting him walk the half-mile to school.

    Here's another example: Recently at work there was a minor fracas when group A published their planned work based on group B's input aka *implicit* buy-in, but without group B's *explicit* buy-in. This made group B unhappy, because they felt that their input wasn't been taken (even though it was). The solution? Group A set up a regular meeting to communicate on their various projects with group B, making sure to get everyone's buy-in explicitly.

    Here's another one: My co-author on the VB version of my WinForms book has been working like a dog on his new job and his new baby and the VB port of my book. However, since most of his communications were with the publishing company directly, I didn't see most of the work that he was doing and, because of our tight schedule, that caused me to worry that we wouldn't make it. The solution? I asked him about it and he told me of the pile of work he'd done that I didn't know about. He also volunteered to make sure to cc me on all of his email related to the book.

    And here's my favorite example: For a long, long time, MS was labeled (and is often still labeled) as an "evil" because of a perceived uncaring about developer's hopes and dreams. Ironically, with a software engineer at the helm, all of Microsoft's decisions are driven by that need to meet the needs of 3rd party developers. The issue was communication, both in letting internal folks make their intentions known to the external folks and in getting the hopes and dreams of external folks into the planning processes of internal folks. It's my belief that the reason that Adam, Becky, Brad, Brian, Chris, Chris, Don, Duncan, Ed, Eric, Kent, Lutz, Martin, Sara, Scott, Tommy, and tons of other MS employees are not only not reprimanded for our blog posts, but encouraged, is so that our intentions can be known to external folks. And believe me, when someone external puts a substantive comment into their blog and one of the thousands of MS employees finds it, it makes its way into the inboxes of the internal MS employees that use that feedback. This need for bi-directional communication between internal and external folks at MS has driven all kinds of new ways of doing things and you're going to see a whole lot more of that at the PDC.

    I could keep going on for days about problems in my life that are solved with communication and could have been avoided with communication up front. In fact, I'm started to get a feel for it when I realize that my communication could have been better and what problem I'm going to have because it wasn't. Also, I've recently started to try to really concentrate on what my friends and family are saying when they start conversations with me while I'm working. (Previously I would continue working, giving a grunt now and again, as necessary.) This little thing has made a big difference. Of course, lots of folks way smarter than I already know this stuff, but to a geek who only learned how to communicate with other humans relatively recently, this is deep thinking! BTW, don't tell my sister-in-law with the Master's degree in communications. We give each other crap all the time on any number of topics and the idea that she knows more about what's really important in the world would give her all kinds of extra ammunition (which she rarely needs anyway... : )

    Buffering .NET Console Output

    Tuesday, August 19, 2003

    Doing some ad hoc benchmarks, I found that my compute/IO intensive program was significantly slower in .NET than in native C++ (here's a more rigorous test showing the same thing). However, when the IO was taken out (Console.Write), the test showed that the computation in .NET and in native C++ was nearly the same (with C++ still having a slight edge).

    My .NET IO code looked like this:

    static void OutputIt(int[] vect) {
      for (int i = 0; i < vect.Length; ++i) {
        if( i > 0 ) Console.Write(",");
        Console.Write(vect[i]);
      }
      Console.WriteLine();
    }

    In tracking down this disparity, Courteney van den Berg noticed that, unlike STL IO streams in native C++, .NET Console output is not buffered. A simple manual buffering using a StringBuilder brings the performance of .NET back in line with native C++:

    static void OutputIt(int[] vect) {
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < vect.Length; ++i) {
        if( i > 0 ) sb.Append(",");
        sb.Append(vect[i]);
      }
      Console.WriteLine(sb);
    }

    Instead of buffering manually, I could have turned on buffered console IO by reopening console output with a buffer size:

    static void Main(string[] args) {
      using( StreamWriter bufferOutput = new StreamWriter(Console.OpenStandardOutput(1024)) ) {
        Console.SetOut(bufferOutput);
        // Use Console.Write (via OutputIt)...
      }
    // Remaining buffered Console output flushed
    }

    // Console output now buffered
    static void OutputIt(int[] vect) {
      for (int i = 0; i < vect.Length; ++i) {
        if( i > 0 ) Console.Write(",");
        Console.Write(vect[i]);
      }
      Console.WriteLine();
    }

    Why isn't Console output buffered by default? Unlike in C++, which has deterministic finalization, in .NET, console output would have to be manually flushed or closed (closing causes a flush). Failure to do so can cause console output to be incomplete at the end of a program. Notice our careful use of the "using" block in the code above, causing the output stream to be closed at the end of the block and the remaining buffered output to be flushed, even in the face of exceptions. Forgetting to use the "using" block or forgetting to manually flush or close in a finally block, can cause console output to be lost. Rather than imposing the new burden of manually closing the console output, .NET architects opted to turn off buffering by default, while still letting you turn it on at will.

    The real goals of marketing?

    Friday, August 15, 2003

    I've long lamented that I have no clue what the basics of marketing are and therefore I've been at the mercy of actual marketing people whose skill I can't judge. In fact, I so miss this important knowledge in my life that I interviewed for a marketing job at Microsoft (although I was in no danger of getting it). A *long* time friend of mine, Dave Stroble, said that I was too "customer-focused" to be in marketing, anyway, and I should be glad I'm not in that field. When I asked how that could be (isn't customer focus the core of marketing?), he went on to say the following:

    "Marketing is not about giving the customer what he wants, or even finding out what the customer wants and trying to get engineering to create it. It's about trying to sell the customer what you already have -- whether that's product, talent, or pre-conceived notions. If the needs of a customer occasionally overlap with an actual product, that's merely random coincidence.

    "Marketing people are customer-focused in the sense of always thinking about why customers aren't buying enough stuff, and how to get them to buy more. You're customer-focused in the sense of caring about what customers need, and helping them accomplish it, even if that doesn't result in selling anything.

    "But don't take it so hard. It's not as if I said you were too honest to be a banker, or too smart to be a teacher. (God, what if girls thought you were too handsome to be sexy?)"

    While I find this cleverly stated (even though I'm nowhere near too sexy for girls : ), I sure hope this isn't the real goal of marketing. My hope is that it's about taking a solution and letting folks that have the matching problem know so that you can trade your solution for their money and both consider yourselves lucky. Is this a naive view? Anyone with real marketing training want to chime in on the real goals of marketing?

    I'm no hero

    Tuesday, August 12, 2003

    In yesterday's post, I did not mean to imply that I was some kind of internal David against the MS Goliath. I am in the majority of employees when I say that I want to keep in mind what's best for the customer. The only issues, really, are what is best for the customer and how can those needs be met within the limits of our resources. We do spend quite a bit of time arguing over those, however. : )

    I speak for the trees

    Monday, August 11, 2003

    After a few weeks at Microsoft, when I was feeling particularly frazzled with my work and travel schedule, Peter Drayton pulled me aside to reinforce what I'd heard before: the first 6 months at MS suck for everyone; after that, you either hate it forever or you can't ever imagine working anywhere else. At that point in my budding MS career, I was leaning towards the former. Peter, having been there, said that he'd gotten a piece of advice that had seen him through.

    The advice was simple: have an agenda. The idea is, no matter what projects you work on, no matter what groups you go to, no matter what tasks you're into that day, to have an underlying agenda that pushes you forward and drives your decisions. Businesses call such a thing a "vision statement." Authors call it a "story." Whatever you call it, it's always helpful to have one and here's mine:

    "Remember what it's like to not work at Microsoft."

    That's it. That's my goal. Of course, as with all things, Dr. Seuss says it better than I can:

    "I am the Lorax. I speak for the trees. I speak for the trees, for the trees have no tongues."
    I consider it my mission to speak for the thousands of developers that I've known and talked to over the years that have no tongue inside Microsoft.

    This came up just this morning on the phone with a colleague of mine at MS. He said, "We need to maintain the value of X." I replied, "I don't care about the value of X. I care about enabling our customers to get the most out of our products." Of course, there are hundreds of people concerned with X inside of MS and they would be less than happy that I'd dismissed the value of it, but that didn't matter to me. What mattered was being the kind of developer advocate inside of MS that had helped me when I wasn't there and to be a constant reminder to my colleagues of the needs of those folks.

    Since MS was founded by developers and run by developers (which has its pros and cons), I plan on being more successful than the Lorax.

    Positive Affirmation

    Sunday, August 3, 2003

    I woke up at Don's house one day last week utterly convinced that I was going to win the lottery that day. It was 6:30a, which is early for me, but I had an 8a meeting (*very* early for Microsofties), so I had set the alarm. Tim, who was also staying at Don's that week and with whom I was sharing a room (separate beds : ) was on Eastern time, so had already accidently woken me at 6a that morning on his way to the door (it's not his fault; I'm too long for the bed and it's a tight squeeze to get past me when I'm I'm in it). I must've had some strong dream between 6a and 6:30a as I lay there in and out of sleep.

    The premonition was so strong that I recalled the epilog from one of the first non-comic Dilbert books in which Scott Adams talked about his belief that there were multiple parallel universi and that by process of positive affirmations, he'd moved his consciousness into one that had attained great success in spite of his abysmal drawing abilities (this was before his TV series was canceled).

    So, all morning, in classic positive affirmation style, I had "I will win the lottery today" running through my head. It swamped all other thoughts, except those of whether I wanted the annual payment or the lump sum ($25M or $13M, respectively) and how I was going to spend the money.

    My first purchase was to be a two-week trip for my entire extended family to Hawaii where we would decide how rest of the money was to be spent. The idea was to devise a plan wherein every adult member of my family could get a life-changing amount of money, e.g. $100K, to use to follow their dreams, but awarded only in a manner that wouldn't actually cause more harm than good (as large sums of money can do [or so I've heard...]). Then, I called my sister-in-law to ask her where, money being no object, she would want to live. I've been looking for houses in her neighborhood lately so that we could be closer ("It takes a village to raise a child.").

    Right away, she was suspicious of my question, "Why? Are you going to win the lottery?"

    "Yes," I said, confidently.

    "Really? How do you know?"

    "I woke up with a 'feeling,'" I said, unashamed.

    "How often have you had these feelings and they've come true?" she asked, judging her odds.

    "Never."

    "Oh," she said, disappointedly.

    "No. I mean, I've never had a feeling like this before," I corrected her.

    "Oh," she said, this time more excited. I've also loved that about my sister-in-law. She's very open-minded. She never once questioned my sanity (out loud), but instead started planning where she wanted to live. Her conclusion is that she'd want a nicer house very close to where she currently live, but basically, that was all. "I like my life," she said.

    That was my conclusion as well. I have things that I want to do that aren't likely to generate an income stream, e.g. figure out how money works, but my life is a good one and doesn't need major changes. It was fun to go through the mental exercise and I would certainly have been happy to win the lottery that day, but it's OK that I didn't. That early morning feeling lead to positive affirmation of a different kind.

    No huggy, no kissy, until I get an RSS feed

    Sunday, August 3, 2003

    Before RSS took over, I had a folder named "Daily" which had links to all of the URLs that I surfed to on a daily basis. One problem was that for the sites that changed daily, it was a pain to decide what was new. An even bigger problem was the ones that didn't change daily. Eventually, the pain of surfing to them daily was outweighed by the pleasure I would get when those sites were finally updated. A bunch of my friends' infrequently updated blogs fall into this category (you know who you are : ).

    Sure, RSS is useful to track Scoble as he shirks his moving duties, but even more useful to track Tim when he eventually does update his blog. With RSS, I don't have to experience any pain surfing to Tim's blog day after day. Instead, I let SharpReader poll Tim's blog and when it's finally updated, I'll know about it. All gain; no pain.

    What that means, unfortunately, is that I only read blogs with RSS feeds, because I've long ago gotten out of the habit of surfing my "Daily" folder. So when Josh Trupin (editor of MSDN Magazine) gave his reasons for being out of the office on Monday, he had to send me an email with a link to the description of his horrific train injury detailed on his blog. As fun a writer as Josh is, I won't go back (unless Google brings me there) 'til he's got an RSS feed. I've been hurt before; now I'm older and wiser and require an RSS feed before I'm willing to wed myself to a blog.

    My First .NET Show

    Monday, July 28, 2003

    In many ways, my list of "My First" articles lately have been written out of duty to all of the developers that have always wanted to work at Microsoft, but haven't yet been able to. I first applied for a job @ MS as a summer intern in 1988. I was turned down while another guy down the hall of my fraternity was accepted. He spent all summer building LCD panels into one giant screen and I spent all summer writing FoxPro code. I wonder if he still works here. I can't for the life of me remember his name. David something...

    Anyway, every time some new, fun, cool opportunity comes up, I feel like I have to take it just so that I can share it with the folks that don't yet work here (seems like they're hiring everyone, though, so it shouldn't be much longer : ). This time, I got to be in an episode of the .NET Show. I was to be 15 minutes of code demo after Brad Abrams and Anders Hejlsberg reminded folks that .NET wasn't just about web services. There were all kinds of folks that Robert had on tap to give the demo, but they were all busy, so eventually they got to the last monkey in the barrel and had to settle for me. : )

    I flew up this morning and had to call MS information: "Hi, I'm a Microsoft employee, but I'm new. Can you tell me where to go to get the MS Studios?" This in spite of the fact that I'd been there less than two weeks before! (I'm terrible at remembering anything that doesn't have a lot of parenthesis and braces in it). They showed me to Green Room #2, where they had some food waiting, just like I was a real "talent". Maybe the food was really for Brad and Anders. Maybe the food was for Nick Hodapp, Project Manager for Visual C++, who was in the makeup chair when I arrived. Nick was there to remind people that MS is serious about C++ both in the native and managed spaces and to show off the port of Quake II to managed C++.

    While I waited my turn in the makeup chair, I watched Brad and Anders do their thing and made sure my demos worked. I was amazed that Robert never stopped the shooting while he did his interview. He did the whole thing in one take, which puts quite a burden on me to get my demo right the first time! I also spent some time eating the Green Room food, IMing my wife (she said to make sure not to use too much blue eye shadow or I'd look "trashy") and giving the makeup artist a talk on the benefits of Wi-Fi (she asked, honest!).

    After Brad and Anders were through, they wandered into my makeup session. I've always wanted to meet the creator of C#, but not while having my eyes done... Anyway, Brad and Anders were having a debate about the merits of a new optimization of the .NET framework and it was really cool to see how practical Anders was. I don't know why, but I imagined a guy that could come up with something as clean and simple as C# to be pretty academic. That wasn't the case at all. His view of the debate was that he wanted to see a few uses of a proposed new feature before he even thought about including it, as opposed to judging it on the basis of it's "coolness" as can happen when engineers gather together in groups. That brief chat made me feel better about having him in charge of my favorite programming language.

    After having just the right amount of blue eye shadow, I sat up on stage with Robert and Nick and my new friend Bob, who ran the entire shoot. He was like the voice of God, being only heard and not seen from his control room in the bowels of MS Studio. He and I bonded quickly as we settled into the banter of trading insults familiar amongst the wiseasses of the world (now *that* sounds like a cool domain name! : ). Robert was very causal and very smiley, very different from the seriousness he portrays on film. Nick was very polished and gave such a compelling demo of the managed C++ Quake II port that I couldn't help but jump in and beg for more. I, on the other hand, said the word "crack" and mentioned my colleague as he IM'd himself onto my computer screen, both times making Robert roll his eyes at me (off camera, I'm sure). I also went off into la la land once when I answered a question that Robert hadn't asked, causing Nick to jump in with an answer.

    All in all, having yourself filmed for posterity was pretty different from giving a talk. It was nice, because I had Nick and Robert to play off of and Robert was very good about moving things along. It was hard because, unlike a talk, there were things that I said that I wished I hadn't merely because they are permanent. Hopefully it went over well as a whole. I don't know if I'll be able to watch it myself. Someone please tell me how it is when it's published next month...

    Windows XP Remote Assistance Rocks!

    Wednesday, July 23, 2003

    I just had a "Windows Moment." I was on the phone with my Dad who has Windows XP and was having trouble. Since he paid for my computer science degree, he assumes that I'll be his tech support. In fact, everyone in my family assumes I'll be their tech support; it's annoying as hell! I don't know how support folks diagnose and fix problems over the phone all day long. More than 5 minutes and I'm ready to say, "How much was that computer science degree, Dad? I'll write you a check."

    Anyway, after trying it for about 20 minutes (and failing), I asked him if he had the Remote Desktop settings on his My Computer->Remote tab, thinking that I could use terminal services to solve his problem. Of course, since he was running XP Home, he didn't, but he did have Remote Assistance. So we tried it. And even though he's in the back woods outside of Fargo, ND and on dial-up (isn't this a commercial for Windows XP?), he was able to email me a request for remote assistance (Start->Help->Ask for assistance->Invite a friend to connect to your computer with Remote Assistance) and I was able to connect to his computer (through my firewall!) and solve his problem (half of Office '97 was installed on C: and half on D: and wasn't happy about it at all).

    Wow. That's a feature that made my life better.

    Using GotDotNet Workspaces For Commercial Work

    Wednesday, July 23, 2003

    When I visit Redmond, I share an office with Andy Oakley, the PM for GotDotNet Workspaces. Workspaces was recently released from beta to v1.0 and when that happened, Andy sent around feedback from users.

    Of course, folks love it in general (even some hard-to-please MS internals), but I was surprised to see to some folks were using private Workspaces for their team's main source code base. I shouldn't have been surprised; this makes a lot of sense. Private workspaces provide a protected space for file sharing, discussion, bug tracking and source code control. The last time I set up a commercial software development team, I needed weeks to get all of this picked out, installed and working and I needed an IT guy to keep it running and backed up. I remember hearing about a 3rd party that was going to bundle all of this together for a fee, but never got around to it. With Workspaces, MS already provides the whole team development environment, including VS.NET integration and a web interface, and it's free! Plus, with a private workspace, only folks on your team get access.

    IMO, the only big piece that was missing from Workspaces was a way to pull down all of the source onto a build machine for regular automatic builds. For commercial work, this is key. So, Andy, tired of my whining, built a command line tool for pulling down all source from a GDN Workspace (and put it up in it's own GDN Workspace). Personally, I'd be slightly happier if it took arguments from the command line instead of a .config file, but that's easily added from the Genghis CommandLineParser class for those that are interested. Enjoy!

    My $5 Digital Music Experiment

    Tuesday, July 22, 2003

    I *really* want to own my digital songs, so I've been dying for a real site to purchase them one at a time, instead of buying entire albums I don't want or ripping the songs off of the albums I do own. Towards that end, I was excited about BuyMusic.com and immediately spend $4.95 on five Avril songs. Overall, it was not a happy experience.

    What I love about BuyMusic.com is the site:

    • The web site is very usable and full-featured, making finding, listening to and ordering artists, songs and albums easy
    • The price is right: $.99/song and $9.49/album
    • I really wanted to immediately find the web service so that I could write a program to go through my wife's bootleg mp3s and purchase them

    Unfortunately, I hate BuyMusic.com because of the Digital Rights Management (DRM) experience:

    • On one machine, I could listen to all of the songs, but only after a "DRM upgrade" (whatever that means)
    • On another machine, I had to do systems administration to play a song (DRM doesn't like it when you're a guest and an administrator in the same account). This is fine for me, because I can chase the error to the web page and do the systems administration on my account, but what about normal people? Then I had to do another DRM upgrade. *Then* I had to log in with my user name and password on *every* song! That means I have to roam around to every machine in my house that might possibly want to listen to the music, because only I know the email/password for the songs I buy. What a PITA!
    • I'm allowed three machines? Why? I can take my CDs to any machine in the house and my cars. I want to own this music for life and I *know* I'll have more than 3 machines before the end of it. I tried it on four machines and it didn't turn me away, which is nice, but how long will that last?
    • How are these WMA files going to work with my mp3 player? Even if the format works, will the DRM get in the way?
    • What about if I download a bunch of songs on my way out the door? If I'm on an airplane, I can't jack into the Internet to obtain the license and there was no "pre-license" batch mode that I could find to save me from obtaining the licenses one at a time

    The whole experience made me want to cry. The site was so great, but the playback was *so* hard. Why do I have to be treated like a child? I'm dying to pay for the music I want, but I don't want to be penalized for it. I really wanted to find the inevitable hacking tool to strip the DRM off of the music I downloaded so that I could use it more freely, but what's the point of that? This kind of hacking would break the license agreement and is no better than downloading mp3s (although the the latter is a hell of a lot more convenient).

    My First Visit to MS Studios

    Thursday, July 17, 2003

    I went with Erica Wiechers (.NET Show heart throb) to visit MS Studios today. Ostensively we were there to preview the Applied XML Developer Conference videos, some of which Erica will be turned into MSDN TV episodes. However, as long as we were there, Bob Snyder gave us the nickel tour.

    The front entry was even more secure than the normal MS buildings, being encased in wire fencing and not yielding to my badge (we had to be let in from the inside). Once in, it was a big building with lots of open space and fun decorations. I got to see several blueprints of famous imaginary places, e.g. the spaceship from Lost in Space, the Addams Family house and the island from Gilligan's Island. I got to see the two green rooms where "talent" gets ready in the full locker rooms, then relaxes on the coach 'til it's their turn (although neither room is green). I got to see all of the studios, including standing on one of BillG's markers, seeing the set where he interviewed with Larry King and the other set where he recorded his antitrust testimony. I also got to see the set for the .NET Show, which looks like the inside of half of a giant bowl, so that they can blend in custom backgrounds, both physical and logical. I go to see all kinds of cool a/v routing and mixing equipment, putting my one little PC attached to my home theater system seem so pathetic in comparison. I even got to see some live footage of Steve Ballmer that they were filming that day (man, he gets excited when he speaks : ).

    In general, I've been getting to see and do a lot of cool stuff here at MS. Recommended.

    Alan Cooper's Has A Dream

    Monday, July 14, 2003

    In addition to bending my head back during my flight lesson, Alan Cooper always manages to bend my brain back, too. Here's a guy that invented drag-n-drop UI development umpteen years ago and he's been in the business ever since, mostly doing interaction design, but lately trying to tackle the problem of software management. His main thesis is that "web designers are called programmers, programmers are called engineers, engineers are called architects and architects are never called." He justifies this statement by comparing architecture to real-world architecture, which is very different from what the IT industry has co-opted the term mean.

    For example, in the world of physical buildings, an architect meets with the clients to understand their needs and listens to their ideas. He then designs a building via a series of increasingly specific sessions with the clients to understand what they need and with engineers to understand what can be done. He uses these interactions to produce blueprints to hand off to the engineer. The engineer decides how to build the building, e.g. what materials to use, what to build or buy, what labor is needed, etc. Before we had mass-produced parts and giant spec books describing every material under the sun, this often required experimentation, which would also feed into the production of a more detailed set of plans to hand off to the construction workers, who do the actual building of the structure. While the structure is built, the engineer and the architect checks in to make sure that things are meeting their requirements and, in fact, it's the engineer's job to sign off when it does. Likewise, there are inspectors that check to make sure things are up to code at certain phases of the project.

    In the world of software, we've got inspectors, they're called QA staff. We've got construction workers, they're called programmers. We've got engineers, they're called software engineers, even though we have yet to decide what being a "software engineer" means (often it's just another fancy word for "programmer"). We sometimes have architects, but we tend to rely on the combination of engineering and usability folks, most often skipping the usability and most of the contact with the customer altogether.

    Alan's view of the world of software is that, because we don't have this very interactive role that really corresponds to the architect very often, non-technical management really has no idea what's going on in the software construction process. Instead, they have to rely on engineers and programmers to tell them things, when they feel like it, and those guys lie (or plain don't know). Likewise, because there is so little architecture, what comes out the other side is often not what the users want anyway.

    In Alan's world, architects fill the role between engineers and customers and non-technical management, designing software that users want and communicating what's going on with management. Likewise, engineers design software to spec that works under stress; programmers build software that doesn't crash; QA checks to make sure that this all happens the way it should.

    One of the benefits of Alan's view is that before engineering happens, architects figure out in a detailed and thorough way what needs building, handing complete specs to the engineers. Likewise, before programming happens, engineers run the experiments and make the technology and resource decisions before any code is written, passing off details specs to the programmers. These details specs also flow to the QA folks, which uses them along with their own quality standards to make sure that the software is right before it ships.

    If this seems silly, think about an inspector signing off on a house before the foundation is poured, a construction worker pouring the concrete before the plans are done or the engineer deciding on the materials of a building before he knows if it's a house or a mall. Software is certainly more fluid than concrete, but it's not so fluid as we like to believe, as evidenced by the number of failed software projects and the cost overruns associated with them.

    We think we're doing architect/engineer/programmer now, but Alan disagrees. What we have is software being hand-made by craftsman from the iron age, but reproduced like appliances from the industrial age. What we need is real engineering for the information age. Alan puts it nicely, "We're standing at the front edge of the information age with really sharp tools from the industrial age."

    Of course, what Alan's talking about is the standard waterfall method of software design, which is what I learned in software engineering school. So why don't we do it? Because we don't like drawing up blueprints. We like to make the lights go blinky, blinky on the monitor. Building a shed in your backyard is quicker and easier without an architect or an engineer involved, but is that how you want your house built?

    Another benefit of this model of architect/engineer/programmer is that it gives non-technical management much more visibility into and control of the process. You may not think so, but this is good. Right now, the only control they have over the process is the schedule. We say, "That'll take two years," and they say, "You've got four months." Why? Because they've been down the "two year" software process before and gotten burned ~100% of the time, whether the software ships late or it doesn't ship at all. At least if they say "four months," they've only lost 1/6th of the money when/if things go bad. If we want to take the giant hammer of schedule out of their hands, we've got to give them something else so that we have the time we know we need to build quality software that we can be proud of.

    I don't know if Alan's right or not, but I sure want him to be. As an architect, I want the tools and the opportunity to design something that the customer will want (I've been down the other road before and it never ends well). As an engineer and as a programmer, I want to build something that will be loved and used when I'm done. Isn't that what we all want?

    My First Flight Lesson

    Sunday, July 13, 2003

    Normally a title like "My First Flight Lesson" would be a metaphor for something else because I'm generally much more engaged by mental pursuits than physical ones. However, in this case it's literal; Alan Cooper (the Father of VB) gave me a lesson in his plane (a Piper 6-seater).

    Tim Ewald and his wife were staying at my house after the Dev.Conf., so Tim and I and the Sells brothers went to the local little airport to pick Alan up when he flew for an Saturday afternoon lark. When we got there, Alan invited us up for a sight-seeing trip. I volunteered to sit in the back with the brothers, giving Tim the front seat, but Alan insisted that I sit up front in the co-pilot's seat, clearly having something in mind.

    After we took off and Alan took us out of PDX airspace at around 2400 feet, he told me to take the yoke because he was turning off the autopilot. After that, he took me through part of a real lesson, including playing with the flaps via the pedals at my feet, banking, trimming, descending, leveling off after a descend and in general, crapping my pants. Flying a plane was not what I expected to do that day, let alone so close to the ground with non-trivial winds and thick cloud cover. Not one do we have plenty of bumps and *sideways* motion to make mere riding a harrowing experience, but I had my boys and Tim in the back with their lives in my hands in the front. I find the sensation beyond my feeble powers of description, but it was fabulous and terrifying and emproudening all at the same time. And at least I had control. All Tim in the back got was the terrifying part!

    Alan said that I did well and had a natural ability to keep the nose up (apparently that's a problem for newbies). Luckily, because he didn't want to make the folks in the back puke, he didn't turn off the engine like he said that he would normally do. Apparently there's nothing like cutting the engine to give a new pilot experience with what actually happens (apparently the plane doesn't drop like a brick no matter how many I were to drop in my shorts). Also, he said that normally he'd make me take off and land, but only in a Cessna, which has special landing gear for newbies, whereas had I done poorly on the Piper, I could've caused $200K worth of damage. On the other hand, while I was relieved not to experience the wonder of zero-engine flight or my first landing, I'm disappointed not to have those experiences as well. It was pretty damn cool to have full control in all three dimensions. That is, except when we overflew the helicopter that the tower didn't warn us about and that we didn't see 'til we were over it. Both Tim and I dropped some bricks when that happened...

    The Killer App for Web Services

    Friday, July 11, 2003

    After watching Amazon's amazing presentation at the Dev.Conf., it hit me that Amazon.com is the killer app for web services. Not only are they technically cool, but they have two business models for themselves and their associates built right in:

    1. I can build a business on their back-end data, selling targeted stuff to my customers, using their services to do all the hard stuff on the back end
    2. I can use their front-end to sell my own products

    Amazon has turned the infrastructure on which they build their own business into a major revenue generator for not only themselves, but for associates. And, if they wanted to take it further, Amazon could provide all of their payment, distribution and storing/querying data as web services for things that weren't even available for sale on Amazon.com, e.g. medical supplies or porn, removing the need to build all of these services yourself. In fact, they're already planning on doing this for payment services.

    *That's* what web services are supposed to enable. *Wow*.

    Applied XML DevCon Trip Report

    Friday, July 11, 2003

    Dave Winer's Keynote:

    • Users care about you software working, not *how* it works
    • Users don't want to be controlled
    • As developers, "we're very impressed with the complexity that we can understand"

    Don Box:

    • "No one that gets laid actually replaces the CPU in their computers anymore. And, since they don't get laid, they can't reproduce and natural selection will take it's toll. Likewise, objects are not meant for field replacement."
    • Building on abstractions means that the abstraction needs to be kept constant
    • the wire is god. schemas are relative to your needs. the same XML instance doc can be many different schemas in a pipeline
    • I missed why the abstractions in a service-oriented architecture are somehow better than those in an object-oriented architecture, except that maybe SOA abstractions are courser grained, but that can be true of OOA, too, can't it?

    Brian Jepson:

    • WAP is just another XML format to product that exposes your data to WAP-enabled devices, e.g. phones
    • Very cool to watch Brian control his presentation via his cell phone (nothing to do with XML, but very cool never the less). He was using a Mac and didn't know if a niche OS like Windows had apps that did such things (although he did find this that might work)

    Don "XML":

    • In NJ, they teach middle school kids HTML, XML and PowerPoint (holy cow!)
    • Lots of folks asking questions, evidently interested in SVG and/or declarative-based UI models

    Patrick Logan:

    • Patrick gave his talk sitting down, which didn't help him keep the audience's attention

    Ted Neward:

    • EJB 2.1 for web services looks pretty easy
    • "Swing sucks. People are using WinForms to access J2EE web services."
    • "Sun has drunk very deeply of the idea that web services are just CORBA.Next" aka Sun views web services as just another RPC, which means that they use rcp/encoded instead of doc/literal

    David Ing:

    • Don't take "rules" from speakers at conferences. You can be entertained by such talks, but you need to make your own decisions

    KeithBa:

    • Keith starts right where I love -- in the code. What better way to show the new programming model and features of WSE 2.0 than to jump right to the code? Fabulous
    • And not only did he do a fabulous job writing code to demo WSE 2.0, he did it by building a heckle application that the audience loved (and took full advantage of : ). You are a master, Keith
    • And! His application is a great example of the need for the flexible model that WSE 2.0 provides and he brings it right back around how his amusing, seemingly trivial app is really not suited for an RPC-style (which we should eschew anyway). Nice
    • And then Dave Winer jumps in to accuse him of saying that there is no such thing as asynch; there is only polling. Keith is way over the top nice about it and the audience disagrees with Dave pretty much as a whole

    Speaker Panel:

    • tons of controversy; end result is that XML solves a huge number of problems and there's no reason to do "this vs. that" because XML allows everyone to co-exist and interop (although programming may be needed to gain the latter)

    Ken Levy:

    • First time showing these plans in public (off of a 2am build)
    • Showed off cool new XML editor integrated into VS.NET:
      • showed red squiggles and helpful error messages about invalid XML
      • can select text and have it wrapped in XML comments, CDATA blocks, etc.
    • showed integration of errors using DTD files, i.e. checking elements that don't have appropriate attributes as defined by the DTD, etc.
      • will reformat your XML
      • may provide outline view for drilling into large XML docs
      • lots of intellisense based on XML/DTD/XSD tools
    • can create schema from a DTD inside of VS.NET
    • can infer schema from an XML instance
    • will enable custom mappings of XML namespaces to corresponding visual editors, e.g. showed an example of editing SVG: first view is the rendering of SVG; second view was code. If you change the code while you're also looking at the SVG view, the SVG view is updated on the fly
    • showed interactive XSLT debugger
    • will be releasing these tools on the XML Tools page for use w/ VS.NET 2003 in the fall (tentatively)
    • send Ken Levy the things that you'd like to see in the XML tools space

    Jeff Barr

    • Amazon is able to turn around small features very quickly and that's the corporate culture
    • they spent $300M on distribution centers and $900M on technology
    • when folks were scraping the web, Amazon could have broken those apps, but realized that the folks doing the scraping were building legitimate apps with that data that was good for Amazon, so instead of crushing those folks, they tried to not change the format of the pages w/o a good reason (in spite of the added cost of supporting robot traffic)
    • to support the largest number of customers, they support rich SOAP interface and a REST interface
    • return "light" and "heavy" data, depending on how much info developers want
    • business model for users seems to be picking an unused domain, setting up a site selling something specific, e.g. power tools, then building the whole site using the data and purchasing/shipping services of the Amazon web services. Wow
    • the associate program is hugely successful for Amazon in terms of revenue generation
    • the protocol is loose so that developers have a wide range of choices of what they want to do with it, e.g. if Amazon doesn't have all of the information being requested, they return what they have instead of failing, letting the developer decide if they want to use the info that Amazon provides or fail on their own
    • Amazon versioning: new versions get new URLs. Old versions use new code internally, but return same old data format from same old URL
    • for keeping their own data up to date, Amazon also publishes a set of services for sellers to update their data and will soon be exposing a service for sellers to create new ASINs (Amazon product IDs) for their own products
    • 80% of the requests are for raw XML/REST (with or without transformation)
    • as things get more complex, SOAP will take over

    Steve Loughran:

    • bottom line: SOAP is ready for use in embedded systems (although things can get better and likely will)

    Tarlochan Cheema:

    • the motivation for the sets of web services that microsoft.com is about to expose is for better communication with partners, e.g. avoiding shipping CD-ROMs around, as well as providing real programmatic interfaces for folks that are scraping data from microsoft.com, e.g. top downloads
    • the way that MS stayed at lots of 9s of reliability is with writing good code, of course, but mostly with heavy use of caching

    Tim Ewald:

    • XML schema shouldn't be used for nominal typing; it should be used for structural typing
    • different parts of an XML pipeline can have different XML schemas to check different things

    Chris Dix:

    • "Everywhere is walking distance if you have the time. Steven Wright"
    • Since you can embed non-SVG data and script into SVG, these are the elements needed for stand-alone, cross-platform "intelligent" data that can provide it's own UI

    Aaron Skonnard:

    • "Scott (my code monkey) and I are still in the running for the $1M playing DevelopMentor Survivor. We kicked Don off the island first because he was the strongest and Tim second because he was the smartest."
    • XSD isn't enough to check real business rules
    • XPath is more flexible
    • Can write a .NET SoapExtension like this:

    [WebService]
    [AssertNamespaceBinding("t","urn:geometry/")]
    public class Geometry {
      [WebMethod]
      [Assert("//t:length > //t:width", "Length must be greater than width")]
      [Assert("(//t:length div //t:width) = 2", "Length must be double the width")]
      public double CalcArea(double length, double width){
        return length * width;
      }
    }

    • Even cooler, because the constraints are part of the .NET metadata of the method, when the docs and the WSDL is generated from the Geometry web service, the constraints can be pushed in as well, making the constraints available to the developer

    My First Press Contact @ MS

    Monday, July 7, 2003

    Today I spoke with Todd Bishop, a reporter from the Seattle Post-Intelligencer ("the Seattle PI"). He was interested in my spout entries about my initial experiences with Microsoft, specifically the BillG ThinkWeek stuff. He called last week, but I didn't call him back right away. Instead, I asked my grandboss (my boss was out on vacation) what I should do. I remember during NEO that MS has very clear instructions about when to talk to the press, i.e. never. Of course, some folks at MS talk with the press, but unless it's specifically part of your job, you're supposed to refer the press to other folks more trained in the ways of the wily reporter trying to get the dirt on MS.

    So, when Todd called and I hadn't yet made my millions on MS stock options (any day now... : ), I thought I'd ask around first before making any career limiting moves. That was early last week. It wasn't 'til today that I got the approval to give the interview. In fact, I'm pretty the MS marketing guy checking on what Todd was up to had a longer conversation than I did. Here's pretty much the entire conversation (paraphrased from imperfect human memory):

    Todd: "Thanks for getting back to me, Chris. I'm glad you went though official channels. That tends to make things go easier."

    I thought that was strange. If I was a reporter, I'd want to track down the defenseless MS employee when they were least expecting it. That's what I figured Todd was up to when he called my direct MS line w/o any introductions. Luckily, I work from home in PDX. Bwa ha ha ha ha!

    Chris: "No problem, Todd. Sorry it took so long to get back to you. They were clear my first day at MS not to talk to the press unless explicitly instructed and I'm new."

    Todd: "Did you get the list of things I'm after? I've already written the story; I just want to check some facts."

    Oh sure, I thought. This is Todd buttering Chris like toast...

    Chris: "Yes. What can I tell you?"

    Todd: "You spell your last name S-E-L-L-S?"

    Chris: "Yes."

    Todd: "What's your position at Microsoft?"

    Chris: detailed explanation of MSDN, DevCenters (including their need in the world) and how I'm doing the Longhorn DevCenter.

    Todd: "Can I just say you're an MSDN Content Strategist?"

    Chris: "Sure."

    So now the reporter's got me giving him more info than he actually wants. I'm in trouble...

    Todd: "And your blog is http://www.sellsbrothers.com/spout?"

    Chris: long explanation about how I organize my site, how the Spout is just the editorial section and that I announce everything from all sections on my home page.

    Todd: "Oh. So your blog is just http://www.sellsbrothers.com. I'll correct that. Thanks. That's all I need."

    Chris: "Really? I expected to be grilled."

    Todd: "Well, you're lucky you waited. If you'd have called last week, I'd have really hammered you."

    Aha! He's just lulling me into a false sense of security for next time! : )

    [ed: Apparently Robert Scoble took the brunt...]

    The Danger of Good Debate Skills

    Monday, June 23, 2003

    I have been in technical arguments many times where I knew I was right and used every once of my debate skills to convince the other person of their terrible wrongness. This can go four ways:

    1. I'm right and they eventually agree
    2. I'm wrong and I turn to their point of view
    3. They get worn down and stop listening
    4. I'm wrong, but they fail to convince me

    Being right is fun, of course, as is finding someone that's willing to change your mind (lots of folks don't like to argue). Wearing a person down is no fun at all, but by far the worst is that I'm wrong and I stay wrong. Unfortunately, as a professional communicator for the better part of a decade, #4 is a real possibility and it's something to really watch out for. Being right is easy. Recognizing that I'm wrong is easy when I'm arguing with someone with good communications skills. Recognizing that I'm wrong when the person I'm arguing with isn't quite up to the task, that's hard to detect and fix.

    Of course, even harder is being wrong and having no one to tell you you're wrong, but I can't blame that on anyone but myself. : )

    Learning to Learn

    Sun, June 22, 2003

    The most important thing that I've every learned is how to learn. I and a few other lucky souls gained this knowledge at the tutelage of one of my mentors, Don Box, during my tenure at DevelopMentor. Not only did I have an amazing thinker to learn from, but I had a enormously difficult topic to learn on: COM.

    When I started learning COM in the early '90s, only a few souls inside of MS really knew it. The only real book in the world on COM at the time was inscrutable and no one with the necessary communication skills and the time to teach COM had yet grokked it fully. Don had written a five-day short course entitled Essential OLE, but only given it a few times, so hadn't really gotten over the hump (as evidenced by the title of the course). It was my job to become the second instructor on COM at DM.

    I've always been one of those people that, when faced with a topic and the proper motivation, could almost always learn it easily. This skill helped me to get good grades, but didn't teach me how to really learn; it was too natural for me to understand how I did it. Unfortunately, COM was too hard to learn "naturally" and there's nothing like preparing to stand up in front of a group of people to motivate you to learn. In fact, the first time I'd had to teach COM, I was so nervous on the last day (when I was to teach the material I knew the least well), that five minutes before my first lecture of the day, I had to find an empty room to hyperventilate. I literally didn't know what I was going to say.

    Unfortunately, I didn't have the option of bailing at the last day of this class unless I was prepared to give up my job at DM. It wasn't the bailing that was the issue; if somebody else that knew the material was available, I could've bailed (that's how cool DM was). Unfortunately, only Don knew it and he was out of town. So, I had only one choice -- fake it. I wasn't proud, but public speaking is like any other form of entertainment and "the show must go on."

    As I was giving the slides that morning on COM structured storage (a particularly nasty topic in COM), I found myself learning how it it worked as I told the story to my audience. All the studying and experimentation I'd done had given me the foundation, but not the insights. The insights I gained as I explained the technology. It was like fireworks. I went from through those topics in a state of bliss  as all of what was really going on underneath exploded in my head. That moment taught me the value of teaching as a way of learning that I've used since. Now, I always explain stuff as a way to gain insight into whatever I'm struggling with, whether it's through speaking or writing. For me, and for lots of others, story telling is where real insight comes from.

    Still, teaching without the foundation of knowledge isn't effective. How do I gain that foundation of knowledge? I consume the available material and ask "why" a lot. If I look at a class hierarchy and it's design isn't immediately obvious to me, I ask why it was built that way and why was that way chosen over another. And to the answers to those questions, I keep asking why 'til I get to something I know already or until I get to a human reason. The reason for not stopping 'til I get to something I know is that I believe that all learning is only as affective as well as it can be tied to what you already know. How easily it is to learn something is directly related to how much you already know about related topics, so the more you know, the easier it is to learn more. However, when humans are involved, aesthetics take over, e.g. the reason that C++ has member initialization lists and Java doesn't is that Stroustrup liked that feature and Gosling didn't.

    The process and benefit of asking why is described well in a novel I'm reading: "It put me in contact with military planners from a dozen nations, and more and more they began to come to me with questions well beyond those of military strategy. ... I didn't think my answers were particularly wise, I simply said whatever seemed obvious to me, or when nothing was clear, I asked questions until clarity emerged."

    What made this process so amazing with Don was that we were both doing the same thing: experimenting and telling each other how it worked, which made for a very tight feedback loop. The loop got better as we added more people, like Tim and Keith, both of whom are also amazing thinkers. Audiences are good because of the feedback that they can provide, but optimized feedback like this got us all leapfrogged very quickly into deep COM thinkers.

    The goal of all learning is clarity. My own method involves taking in the available material, asking a bunch of "why" questions and then telling somebody else 'til clarity emerges. After COM, I've successfully applied that method to learning how all kinds of other technologies work, how to run a business, how to write, how to manage, how to lose weight (50 pounds and holding) and, most recently, how Microsoft works. Thanks, COM (and Don and Tim and Keith and every audience I've every had : ).

    Naming My Feed

    Fri, June 20, 2003

    When I built the Windows Developer News feed on my home page, it was an attempt to build a Windows equivalent of SlashDot. Unfortunately, I'm not interested in keeping up on all the news in the Windows developer space and the few folks that have stepped up to post on this site are largely spammers (although not all of them). Also, in my own feed subscriptions, I find that the ones I'm most fond of are from individuals, not groups. Plus, my grandboss recently put a fine point on it, "I hate the name of your feed. That's not what it is."

    So, I've moved this feed to be just stuff from me. The problem was, I didn't know what to call it. In addition to posting links to stuff I produce, e.g. tools, writings, editorial, etc., my site's feed is really about the things that I find interesting and my personal insights, so I need a name that reflects that. Also, I'm a big fan of puns, alliteration and double meanings (the logo has *3* meanings), so a name with those elements was important.

    As always, when I'm faced with something like this, I turn to the community, specifically my own readers, who seem to have an unhealthy desire to participate in things like this. When I asked them for their input, I was overwhelmed with more the number of responses; and good ones, too (it probably helped that I was giving away a free seat at the Applied XML Developer's Conference [July 10th -- register now!] to the one I picked)! Here're some of the best that I didn't pick:

    • "The Naked Programmer" from Richard Caetano. This has a nice tie in with the logo and connotes the openness I'm fond of in my writings. The problem with this one is only that it already appears on the web.
    • ".Nirvana" from Yaniv. This one goes nicely with the logo and my current technology of choice. However, as much as I like .NET, it's not likely to be the last disciple I embrace, so I don't want to tie myself to it.
    • Sells-A-Go-Go from Michael Weinhardt. This one from a former protege very much appeals to my sense of fun, but it only has one meaning.
    • Longhorn Foghorn from Mickey Williams. Again, this one ties me to a wonderful technology, but one that I'm legally obligated to stay mum about for a while longer. However, if I have anything to say about it, Mickey, you have named the Editor's Blog for the Longhorn DevCenter when it goes live. Thanks!

    The one I did pick was a blend from three guys: Mike Prilliman, Chris Burrows and Roland Tanglao. They each gave me parts of my new RSS feed name: "Marquee de Sells: Chris's insight outlet". This name has tons of wonderful qualities:

    • it's unique on the web
    • it's short and distinctive
    • I share a birthday with the Marquis de Sade
    • the Marquis and I share an unhealthy obsession with our respective writing topics of choice
    • my logo is an abstract of my naked picture (the Marquis's topic of choice : )
    • a marquee is an entrance (like my homepage) with a sign announcing what's new (like my feed)
    • my feed is an outlet for my insights, whether code, writing or interesting things I find I the web
    • "insight outlet" sounds like "inside out," which connotes how open I try to be (ok, I'm stretching on this one, but "insight outlet"
      *does* sound cool : )

    Of course, once I'd picked a name that blends entries from three people, I had the problem of how to award the prize: a single seat at the the Applied XML Developer's Conference. And then I remembered that it's my conference, so all three of them get free seats. Welcome!

    BTW, the Applied XML Developer's Conference is going to rock. Register now before all the seats are gone.

    End-To-End RSS + Comments

    Wed, June 18, 2003

    My RSS 2.0 feed exposes end-to-end support for the comments specifications I'm aware of:

    Several other folks are working on producing and/or consuming the <wfw:commentRss> extension as well, including Joe, Sam, Scott, JamesS and Kevin. JamesD posted instructions on how to do it with MoveableType. Hopefully Dare, Luke and Nick will follow suit.

    Releasing Nested Objects in Rotor

    Mon, June 16, 2003

    Chris Tavares is making more progress finishing up the Ref-Counting in Rotor project:

    class FinalizerObj {
      int n;

      public FinalizerObj( int n ) {
        this.n = n;
        Console.WriteLine("Created Finalizer object {0}", n);
      }
     
      ~FinalizerObj() {
        Console.WriteLine("Finalizing finalizer object {0}", n);
      }
    }
     
    class FinalizerContainingObj {
      FinalizerObj subObj1;
      int n;
      FinalizerObj subObj2;
     
      public FinalizerContainingObj( int n ) {
        this.n = n;
        subObj1 = new FinalizerObj(n * 100);
        subObj2 = new FinalizerObj((n * 100) + 1);
        Console.WriteLine("Creating containing object {0}", n);
      }
     
      ~FinalizerContainingObj( ) {
        Console.WriteLine("Finalizing finalizer containing obj {0}", n);
      }
    }
     
    class TestApp {
      static void Main() {
        for( int i = 0; i < 5; ++i ) LeakAnObj(i);
      }
     
      static void LeakAnObj(int i) {
        FinalizerContainingObj obj = new FinalizerContainingObj(i);
      }
    }

    Running this app under our ref-counted Rotor yields the following output:

    C:\Home\Chris\Projects\Rotor\src\tests>clix FinalizerTest.exe
    Created Finalizer object 0
    Created Finalizer object 1
    Creating containing object 0
    Finalizing finalizer containing obj 0
    Finalizing finalizer object 0
    Finalizing finalizer object 1
    Created Finalizer object 100
    Created Finalizer object 101
    Creating containing object 1
    Finalizing finalizer containing obj 1
    Finalizing finalizer object 100
    Finalizing finalizer object 101
    Created Finalizer object 200
    Created Finalizer object 201
    Creating containing object 2
    Finalizing finalizer containing obj 2
    Finalizing finalizer object 200
    Finalizing finalizer object 201
    Created Finalizer object 300
    Created Finalizer object 301
    Creating containing object 3
    Finalizing finalizer containing obj 3
    Finalizing finalizer object 300
    Finalizing finalizer object 301
    Created Finalizer object 400
    Created Finalizer object 401
    Creating containing object 4
    Finalizing finalizer containing obj 4
    Finalizing finalizer object 400
    Finalizing finalizer object 401

    In other words, all top-level and 2nd-level objects are finalized deterministically. Wahoo!

    Exposing RSS Comments

    Thu, June 12, 2003

    So far, comments have gotten a lot of play in the RSS space:

    However, what's missing is the ability to pull out a list of comments associated with an item. Instead, folks like Sam publish their comments as a separate feed, and then feed readers thread the comments with the content by comparing the elements from the type feeds (as well as all of the other feeds). That works for most standard-sized RSS sites, but what about sites that exposes hundreds of thousands of entries like msdn.com? Cached per site comment feeds don't scale as well as on-demand per-item comment feeds. Towards that end, I'd like to propose another element to the well-formed web's CommentAPI namespace: commentRss.

    The commentRss element would be a per-item URL for an RSS feed of comments. It looks very like the wfw:comment element:

    <wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/"> 
      http://bitworking.org/news/commentsRss/52
    </wfw:commentRss>

    With wfw:commentRss, the RSS reader can pull the comments down on demand, merging them in with the cross-references from other blogs as it does now. In addition, an extension to RSS like this would allow feed readers to subscribe to comments for a particular item, either manually for conversations in which the user is interested or automatically when the user posted a comment for an item.

    Comments?

    Ref-Counting + Rotor Status

    Thu, June 5, 2003

    I just got this email from Chris Tavares (who's doing the lion's share of the implementation work to add ref-counting to Rotor):

    using System;
    class FinalizerObj {
      int n;

      public FinalizerObj(int n) {
        this.n = n;
        Console.WriteLine("Created Finalizer object {0}", n);
      }

      ~FinalizerObj() {
        Console.WriteLine("Finalizing finalizer object {0}", n);
      }
    }

    class TestApp {
      public static void Main() {
        for( int i = 0; i < 5; ++i ) LeakAnObj(i);
      }

      static void LeakAnObj( int i ) {
        FinalizerObj obj = new FinalizerObj(i);
      }
    }

    Under the desktop CLR, I get this:

    C:\Home\Chris\Projects\Rotor\src\tests>FinalizerTest
    Created Finalizer object 0
    Created Finalizer object 1
    Created Finalizer object 2
    Created Finalizer object 3
    Created Finalizer object 4
    Finalizing finalizer object 4
    Finalizing finalizer object 0
    Finalizing finalizer object 3
    Finalizing finalizer object 2
    Finalizing finalizer object 1
    But when I run under Rotor, now I get this:
    C:\Home\Chris\Projects\Rotor\src\tests>clix FinalizerTest.exe
    Created Finalizer object 0
    Finalizing finalizer object 0
    Created Finalizer object 1
    Finalizing finalizer object 1
    Created Finalizer object 2
    Finalizing finalizer object 2
    Created Finalizer object 3
    Finalizing finalizer object 3
    Created Finalizer object 4
    Finalizing finalizer object 4
    Finalizing finalizer object 4
    Finalizing finalizer object 0
    Finalizing finalizer object 3
    Finalizing finalizer object 2
    Finalizing finalizer object 1

    I obviously still need to figure out how to pull the object off the finalization queue, but that will have to wait until tomorrow night.

    Even though they're being called by us and by the GC, this is the first time we've been able to get finalizers working. Wahoo!

    My First API Review

    Wed, June 4, 2003

    Maybe you're getting tired of my posting my "firsts" at MS, but that's the beauty of this medium. I get to say what I feel like and you get to listen or not, as you choose. Mostly this "Dear Diary" format helps me to digest the world around me. Many times, the writing itself has helped me to clear my head. If you haven't tried it yourself, I recommend it.

    So, on with my next "first." Today I crashed an API review. I happen to be on a few internal Longhorn mailing lists and recently got an announcement of a new API that was going up for its first review. I didn't know what to expect, but I hoped at least to see some familiar faces and to introduce myself around.

    Now, the way I work things, I try to really pack myself into meetings when I'm up in Redmond so that I can get the most out of my time away from home (I'm still based in Portland, OR). In this case, I had a meeting scheduled from 9am to 10am in building 5 and then had to truck across campus to building 42 for the API review at 10am. Needless to say, I was late (the only thing harder than finding parking in the sea of cars after 9am is finding your anonymous rental car when you come back for it). Luckily, MS meetings seem to start late as a matter of course, so I hadn't missed anything. However, I was a bit surprised that in more than a month of introducing myself around, there was a room full of 10+ people and no familiar faces. They glanced up at me when I came in the door and seemed a bit confused as to who I was, but didn't ask or toss me out on my butt (it's handy being 6'5" sometimes : ).

    The process was pretty cool. Apparently the team building the API had answered a standard questionnaire from the review team, which included target users, potential security problems and representative sample code that users would be expected to construct. The review team had prepared by going over the questionnaire and prepared topics of discussion (the latter making this review process better than most I'd attended). The API team provided answers to the questions and took notes on how to fix their API.

    I was impressed with the whole thing. The API team was very open to suggestions for improvement, even letting me put in my two cents (I couldn't help myself : ). And the design team gave out just the kind of advice I want all .NET APIs to follow, e.g. use best practice coding conventions in sample code, support IDisposable at a macro level instead of a micro level, expose collections from properties returning IEnumerable (not from the parent object itself), prefer properties over Get/Set methods (as appropriate), don't tack the name of the enumeration type onto the enumeration values themselves, prefer overloads to parameters that can be null, prefer typed parameters to object parameters, etc. In addition, where the API team had reinvented the wheel (they were experts in their problem domain, not the entire .NET Framework Class Library, after all), the review team pointed them at what to emulate and where to look for more guidance. The whole process gave me quite a bit of confidence in .NET maintaining the high degree of consistency that's it's achieved to date (the FCL consistency is not perfect, I admit, but it's a damn sight better than COM APIs ever were and don't even get me started on Win32).

    After all that, I did finally get to introduce myself (the note taker on the API team wanted to know who was complaining : ), I helped name a Longhorn data structure and I met a General PM that I needed to talk to anyway, so it was a useful experience all around.

    Submitting to Billg's ThinkWeek

    Tue, June 3, 2003

    As has been mentioned out in the world, every once in a while Billg takes time to back away from whatever he's working on to think big thoughts. Employees are allowed to influence those thoughts by sending in papers about whatever they want. I heard about this a few days before the deadline and, as I had an idea for something, I wrote up a quick treatment. In spite of the odds against me, I couldn't let such an opportunity pass by w/o even trying!

    I sent my short piece around internally and, because of it's length (I only had time to put together 2.5 pages), I expected to get all kinds of feedback of the lack of depth. Surprisingly, I only got one of those and a bunch of positive feedback, including some useful tweaks.

    After applying the tweaks and running into the limit of time I could spend on it (I did have any actual job to do, after all : ), I sent my paper to the screener that makes sure that Bill's not bothered by trivial things, expecting to hear where to file it. But I didn't hear that. In fact, I didn't hear anything at all 'til today when my own patron St. VP thanked me for my submission, being all kinds of vague about whether Bill will be handed my paper or not, but pointing me to some folks internally about making my idea happen. I took this as letting me down gently, but further emails indicated that my paper *had* been sent along to Bill.

    Now I'm wondering what the heck Bill will do with it. Ignore it? Shred it? Send me an email with a single line, "Make it so, #1?" I'm not sure which one is scarier. After having survive my first encounter with a VP, I wonder if I'll survive my first encounter with it's commander and chief. Keep your fingers crossed. : )

    My First Meeting with a Senior VP

    Sat, May 24, 2003

    On the anniversary of my first month at MS, I took my first meeting with a Sr. Vice President. I'm told that's a big deal. One colleague who'd been at MS for a few years said, "Wow. You must be important. I expect that the first time I'll be in a meeting with a Sr. VP will be at my firing." In my case, it's not that I'm important (I'm not) that got me involved with such a meeting; it's that I have recently been asked to participate in a project that needed to meet with the VP to clarify some review feedback . Or, in other words, it was a pretty pedestrian "here's what we've come up with since the last time we met" kind of meeting. What made it interesting was that it was with a Eric.

    Imagine a company run as a strict meritocracy that's one of the most important and profitable in it's industry. Now imagine that this company has been around for a while and has acquired tens of thousands of employees in a multi-layered hierarchy, with only the best and the brightest surviving and the best of the best rising to the top. That's MS. Billg is layer 1. Eric is at layer 4 w/ a small number of peers. I'm at layer 9 or, as I like to call it, "the bottom." By all rights, that means that Eric should be "5" smarter than me, and I can see him fitting comfortably into that category.

    Had Eric wanted to shred us, I'm sure he could have. Luckily, it was a nice, calm, productive meeting w/ him cutting quickly to the main points (in spite of the fact that he was reading and making notes on our handouts while still listening to our presentation). He also make some pretty interesting comments, especially considering how little time I'm guessing he's had to think about the problem space. At least one comment put me on a path that I like much better than the one I was on (although we'll see how he feels about it at the next review). The comment that startled me most, however, was when he said that he read my site. If this is my last post from inside the big house, you'll know how much he liked it. : )

    My First Month @ MS

    Wed, May 21, 2003

    Today marks the 1-month anniversary of my assimilation. For those expecting references to my "scars," you can be as surprised as I am that there aren't any. In fact, my coming to MS has not really been a big deal. Oh, folks were nice and I got emails from all manner of internal and external folks with nothing but good wishes, but, somehow, I expected something different. Frankly, given the world's impression of MS, I think I expected hazing. In fact, I woke up this morning with memories of dreams involving all kinds of bizarre knowledge- and activity-based initiation rites lead by my grand-boss that reminded me of a cross between my college fraternity and Fear Factor (although maybe I was still reliving my MSDN "morale event" experience : ).

    Why did I expect all kinds of horrible things? Because MS is a very intimidating company; they play to win, seemingly at all costs. This A+ personality trait is certainly reflected inside the company, but there's something else there, too. The part that surprised me was that job #1 seems to be exactly what I would pick: do "the right thing" for the customer.

    In fact, doing the right thing is so important that MS builds a "customer advocate" position right into the heart of their culture; these people are called "Program Managers" (PMs). PMs are not to be confused with "Product Managers," who are marketing folks. Of course, MS has all the standard positions, e.g. marketing, managers, developers, testers, documentation, etc, but they also have this PM position that, as far as I can see, forms the glue for the company and affects everything else. The PM's job is wake up in the morning and think to him/herself, "What's the right thing to do today?" The range of things that fall into this category is far too wide to even give you the bounds, but essentially it's whatever someone else isn't already doing (or isn't doing to their satisfaction : ). Once they identify the right thing to do, they can attempt to take "ownership" of making it happen (your boss gets a say in how you spend your time).

    Once ownership is acquired, that's when things get interesting. PMs have all kinds of responsibility, but no authority. While this kind of position is generally one to avoid in the world of corporate politics, the internal product cycle training video I watched a couple of weeks ago points out that "responsibly without authority" is by design. Instead of ruling by fiat, PMs have to wander around the company finding folks that are involved with what they're doing to get their "buy in" and their help. The way to do that is through old-fashion politics, i.e. gathering consensus, persuasion, trading favors, brow-beating, table thumping, complaining up your own management chain, complaining up your opponent's management chain, etc. It's not just a popularity contest, although being liked certainly helps. It's also about your reputation, as established by your technical chops and your ability to produce, among other things. Under-achievers need not apply.

    In other cultures where the hierarchy is all, such meritocracy can't really work (in spite of lip service to the contrary). There's often too much of an attitude of "who the hell are you to tell me what to do?" to even be allowed to present your case. Luckily, since there's a whole bunch of folks wandering the halls looking for favors, the MS culture makes it OK to work in this manner. That's why the role of PM forms to key to the culture, imo. Oh sure, MS is a real company with a well-established hierarchical chain of command (there're currently 7 people between me and Billg), but hierarchy is only one part of the organization, and arguably not the dominant one (although I'm still new : ).

    In a way, the whole system is kind of like the legal system. In the court room, lawyers from each side argue before a jury, each using every trick in the book to push their agenda and the law is only part of the equation. The jury decides who's right.

    At MS, multiple PMs all wrangle with each other, each using every trick in the book to push their agenda and technology is only part of the equation. Sometimes, it's the folks inside of MS that serve as the jury. Sometimes, it's the market itself that serves as the jury. In the latter case, that's why you sometimes see multiple products from MS that seemingly serve the same purpose, e.g. C++ vs. C#. Those are two groups that both think that they've got the best way to accomplish their goals and they've both made strong enough cases internally to be allowed to compete externally. Probably the reason that each product exists in the first place is because one day some PM probably woke up and said, "MS really needs a C++ compiler" or ".NET really needs a C-like language that's not as hard to use as C++," and look what they got themselves into. : )

    Of course, it's not just PMs that have the responsibility to constantly be on the lookout for the right thing. Everyone is supposed to get up every day with this attitude. It's just that PMs only get to persuade; they don't get to order things to be done (unless they get staff). Since MS is filled with folks all aiming to do the right thing, everyone is constantly committing to help with new ideas. That's why you see MS folks at conferences always busy and always rushing back to their rooms to check their email; they've committed to do way more than a normal human can do because as the "right things" come along, it's darn hard to say "no." That's why I started this spout entry on a Wednesday but I'm finishing it at 8am on a Saturday while the rest of my family sleeps. Even in the last month, I've accumulated a bunch of projects of varying sizes, all of them "right" as far as I was concerned.

    According to the training video, in spite of this overwork and the recent lack of any expectation of riches, folks that come to MS don't seem to ever want to leave. It's that darn culture of the PM again. I've worked at large companies that run by fiat and they suck. Hell, I've worked at small companies that work by fiat and they suck, too. Is it any wonder that, assuming you have merit, once you find a stable, interesting, friendly company judging you on your merit that you're loathe to leave? I find myself cataloging the skills that I think I'll need to be successful at MS and it seems like I've been preparing for this job since I was 12 years old. I've hopped from company to company looking for the perfect fit. DM provided that fit during the boom. Is MS going to provide it from now on?

    My First Talk As A Microsoft Employee

    Fri, May 16, 2003

    On Wednesday, I gave my first talk as a Microsoft employee. I was told that the talk was for a bunch of UK folks that needed to be put on the .NET path and could I do 90 minutes on intro to WinForms in a conference room on campus? I can do intro to WinForms material for hours without preparation, so I didn't do any. Instead, I showed up with my laptop and plugged it into the overhead, where I then spent 10 minutes wrestling to get it out of suspend mode (the world needs faster hard drives!).

    While my HD woke up (apparently jet-lagged from the trip between building 5 and building 43), I started warming up the crowd with questions "How many of you are C++ programmers? How many VB programmers?" The room was split pretty evenly between C++ and VB, taking half of my jokes away (I'm happy to make fun of either C++ or VB programmers equally, but it's less fun when only half the room laughs). Plus, these guys were *way* jet lagged, so getting them to even keep their eyes open in the afternoon after they'd arrived was a challenge, let alone getting them to laugh or even engage.

    And then, because my HD was still shaking off the dust, I asked "Did you hear anything good today?" Predictable, they said that they'd like the story of web services (Don had been there earlier in the morning) and that caused me to launch into my rendition of how WinForms + Web Services provided a wonderful way to keep all of the UI logic on a single machine, as opposed to web applications, where the UI is split between the client and the server. They weren't biting.

    Plus, after diving into some WinForms intro material and having it fall flat (anchoring and docking normally wows 'em), I did a bit of deeper digging into my audience. It turns out that most of them were old hands at WinForms, throwing my planned material right out the window. Luckily, I did find a topic that they're weren't familiar with: href-exes. So, I did my normal href-exe shtick for about 60 minutes, getting them to wake up, ask questions and even laugh a bit at my witty repartee.

    Thinking I was in the clear, I opened the floor for questions. Of course, the first question they asked was the same question I'd have asked if I were in their shoes (as I so often was until about a month ago), "What's new in WinForms 2.0?" And that's where things got shaky again. I had some ideas of where WinForms 2.0 was going in the next release of .NET, but nothing concrete (I've been buried in Longhorn and a whole new culture too deep to dig into WinForms futures yet). Plus, even the things that I did know, I had no idea what I could say. Where these guys under NDA? What could I say to them if they were? What can I say to them if they're not? Even if I'm not supposed to say anything, I want them to like me (every speaker's guiding principle) and I wanted to say something besides "I know, but I'm not going to tell you. <bpffffft>!"

    So, I stammered out what I knew to be some WinForms desires without making any promises on their behalf and hoping no one would ever know (except my closest friends reading this spout entry : ). It wasn't a happy experience. I should have talked with the WinForms guys before my talk so I knew what I could say about the future. Rookie mistake #1.

    Rookie mistake #2: In an effort to stay open to these guys, I wrote my alias on the flipchart and then, while I filled in the domain, kept answering questions. When I looked back at the flipchart, I discovered that I'd written "csells@sellsbrothers.com". Doh! Since it was a flipchart and not a whiteboard, I couldn't even erase it. <sigh>

    All in all, I think I got them jazzed about href-exes, but it was definitely not my finest talk. Luckily, it was internal and to a small group; I would have been mortified to have given that performance at a larger venue. Plus, making fun of VB programmers isn't fun anymore. I mean, they're customers, too. Looks like I'm going to need some new material...

    My First Week @ MS

    Fri, 4/25, 2003

    After my first week at Microsoft *everyone* wanted to know how it went, both internally and externally. I learned some things:

    • I learned that folks at MS will call a meeting for lots and lots of reasons, including at the slightest sign of confrontation or hurt feelings. For a guy that hasn't really attended a meeting in the last decade, this is quite a switch : )
    • I learned how to schedule a meeting w/ multiple people and a conference room (listed as "conf room <bld>" in the address book), all with conflicting schedules and all remotely using Outlook Web Access and without a SmartCard (I was pretty proud of that one, actually : )
    • I learned that no one uses the phone for anything -- instead, they schedule meetings
    • I learned that it's the person that wants something that does the actually scheduling of the meeting
    • I learned that it's OK to open your laptop in a meeting, otherwise when would you get any work done?
    • I learned that it causes quite a stir when you disagree with the technical lead of one of the major pieces of technology that you're supposed to be taking to the world
    • I learned that it's darn hard to find out who to talk to your first week, and that you should take your boss to most of your initial meetings so that s/he can make sure you're getting what you need to get from them
    • I learned that you can mix Exchange and POP3/SMTP to keep your new and your old email addresses going, if you use Office 11 and if you are willing to give up calendar and follow up notifications on your POP3/SMTP account (have I missed something?). I also learned that internal MS support doesn't help w/ such things.
    • I learned that internal MS support is the greatest support in the whole darn world. These people don't let you off the phone 'til everything works. They're amazing
    • I learned that you can volunteer for absolutely anything you think is cool or important so long as you get everything else done, too
    • I learned that it's not good to ask for NDA access to super-secret bits for your friends the week before you start working there (OK, I'm pretty sure I knew that before, but I had to try... : )
    • I learned that the right folks hanging out at lunch can make all kinds of interesting things happen
    • I learned that MS and it's employees is the most charitable company in the country (world?)
    • I learned that the internal resources for MS employees are unbelievable. I could work their my whole life and never take advantage of all of them
    • I learned that it's important to sign up for your benefits immediately if you're going to be remote w/o a SmartCard for a while, otherwise your son may wake you up in the middle of the night with a hard toothache and when you take him to the dentist the next day, the dentist won't be able to confirm your dental insurance (as one example : )
    • I learned that most everyone at MS is very nice (even when they're telling you to f-off)
    • I learned that everyone (and I'm no exception) has a hard time fitting in at first. One interviewer told me that his first 6 months at MS were the worst of his life. I pray that it doesn't last that long for me
    • I learned that after the initial period that few that survive it would ever think of leaving. I absolutely see how that could be

    "Look with favor upon a bold beginning"

    Mon, Apr 21, 2003

    A couple of weeks ago, I was having lunch with my wife at a little Chinese restaurant. My fortune was the title of this spout piece. I immediately associated it with my recent job interview at Microsoft and it made me smile. I had already pretty much decided to take the job, but it was nice that the Universe agreed with me. : )

    Right now I'm sitting in NEO (New Employee Orientation) for Microsoft employees. Not only is it a cool name, but the nice folks at Microsoft provide a wireless network for new folks that can't spent hours w/o one (although I'm the only one that's geeky enough to have his laptop out at the moment : ). I start today as a Content Strategist on the MSDN content team at Microsoft, Corp. I'll be in charge of the Longhorn DevCenter. A DevCenter is a section of the MSDN web site that focuses on a specific technology area, like the XML/Web Services DevCenter.

    Longhorn is Microsoft's next major operation system (and different than Windows Server 2003, which is the OS that Microsoft is launching this month). I can't (yet) say anything more about Longhorn except that it's cool enough that I took a job at MS so that I could get my hands on it. If you are dying for more info on Longhorn, but aren't quite ready to change your employment arrangements to get it, check out the PDC in October. And, if you stop by and say "hi," I'll show you the implant scars... : )

    Discuss

    XML For Humans

    Thu, Apr 17, 2003

    When I sat down to write this piece, I didn't get why the work that Don, Gudge, KeithBa, Yasser, Tim and ChrisAn is doing is so amazing. I mean, I know that they're smart and I know that they're building the hell out of their stuff, but why? It seems like everyone that gets into blogging starts by writing their own blogging engine. It's like C programmers writing editors, C++ programmers writing string classes and XML programmers writing XSD<->Class codegen. Sure, it's a useful learning tool, but earth-shattering? Worth that much energy from that many guys? When they're done, what great problems will be solved?

    Don't get me wrong. I love the that the web makes it easy for anyone to not only publish but also get an audience. I also love that there's a protocol (RSS) that lets me subscribe to my favorite freelance authors in any one of dozens of tools (I'm into SharpReader today). I even like the Dear Diary style of writing because it leads itself to thoughts, feelings and insights that give me greater understanding of not only the topic but the author. As an added bonus, blog entries have turned into everything that's good about mailing lists w/o the endless angle brackets that remove the need to write in coherent sentences. Blogs feel like the kind of democracy we had that lead to the American Revolution when the world was re-shaped with big ideas, written by great authors.

    But does the world need yet another blog engine? Personally, while it's primitive, I find that FrontPage have served me well as a blogging tool. The mental overhead is small, the development is nil and I get red squiggles. It falls down sometimes, but I've spent far less time maintaining the infrastructure for my content than I would if I were to build my own blogging engine.

    On the other hand, while I don't feel the need for another blogging engine in the world, I definitely see value in what those guys are doing. Specifically, they're building apps, which is not something that XML guys are traditionally into. In fact, I'm scratching my head trying to think of another kind of XML-based technology that isn't infrastructure-based and I'm not coming up with one (even InfoPath is a dev-tool). Is RSS really the first mainstream use of XML that hasn't nothing to do with technology for it's own sake? Are blogs the killer app for XML? I know web services were supposed to fill that role, but while they do solve a real problem, they're not for consumers. My aunt in FLA couldn't make use of a web service. However, she could definitely subscribe to an RSS feed and read up on the local news, her job and her hobbies.

    Of course, the beauty of having infrastructure guys building apps is that they get to put into practice what they preach. When stuff is a pain (like every single XML API ever invented and most XML vocabularies), they feel the pain. The difference between us and them is that instead of just wrapping a layer of abstraction around the ugly stuff like we have to, they can actually fix it. I started this piece wanting to shake those guys until they could tell me why they cared so much. How ironic that thinking through the issues in the very medium they're digging into helped me figure out what they were up to. The blog engine work is but the vehicle. They're riding the app train to enlightenment. They're trying to understand how XML can be used to solve problems for real humans. How can I argue with that?

    Priceless

    Mon, Apr 14, 2003

    • Running sellsbrothers.com for one month: $150
    • Round-trip ticket from OR to FL to give a 90-minute talk: $1200
    • My son picking me for his "famous person" school report: priceless

    I don't know how my son picked up on the tiny bit of fame I've acquired amongst a small, strange (but loveable!) group of people, but he did and now he thinks I'm cool. I'm sure it won't last, but I plan to enjoy it while it does. : )

    Oregon & Open Source

    Fri, Apr 4, 2003

    I had an interesting experience yesterday when I was asked by Mike Sax to come to the Oregon capitol building to testify against HB 2892, known as the Open Source Software for Oregon Act. In general, the bill talks about the benefits of open source, open standards and open data formats, most of which I didn't have any issues with. However, I got up at 6a and drove an hour down to Salem because of the following clause:

    "(2) For all new software acquisitions, the person or governing body charged with administering each administrative division of state government, including every department, division, agency, board or commission, without regard to the designation given the entity, shall:
    ...
    (c) Provide justification whenever a proprietary software product is acquired rather than open source software;"

    By requiring state government employees to write a special justifications, this bill erects artificial barriers to adopting commercial software, above and beyond the fact that commercial software requires an initial payment (which should be more than enough of an edge for open source software).

    If you've never been to a government bill committee hearing, I highly recommend the experience. I was in a little hearing room with a bunch of other folks, all interested in this particular bill. I signed my name on the list of folks "against" the bill so that I would have a chance to testify. The chairman called first proponents of the bill and then opponents up to the microphone three at a time.

    Some of the the proponents were teachers and school staff that had put Linux and other open source software to good use in combination with old computers used as thin clients against a back-end server (using X-Windows, I assume). They claimed that they solved themselves all kinds of trouble because open source software was "immune to viruses and security problems" (now *that's* effective propaganda! : ). Some of the proponents were embittered IT staff and new college grads looking to bring some old-fashioned democracy back into a country that had been recently taken over by corporations. It was all I could do to avoid pointing out to them that that the country had been taken over by corporations shortly after Adam Smith wrote "The Wealth of Nations" in 1776 and the budding US government adopted the ideas therein to fund their new country. The basic story of the proponents was that open source was good, so it should be mandated over closed source.

    The opponents, on the other hand, were largely suit-wearing fellows from large groups of commercial software corporations (one of which didn't hesitate to remind the esteemed committee that it's member companies had paid $135M in Oregon state taxes last year). Their arguments were that undoubtedly open source software was clearly already being used by government bodies, that there was no rule against it and that their should likewise be no rules against proprietary software. Only Mike, owner of a small Oregon-based software company, and me, owner of nothing at all of interest, represented the "little guy" on the opponent side (we stuck out because of the lack of either a neck tie or a suit coat).

    19 copies of my written testimony were submitted without comment at the request of the chairman who assured the audience that all testimony would be read. My verbal testimony was limited to pointing out that shackling proprietary software was "bad engineering" because it could easily cost the state of Oregon more money in the long run; maintaining source code is a lot more difficult than maintaining commercial software for normal humans. I also pointed out that being open source did not prohibit viruses or security problems; the first computer virus ever was written on a Unix, the predecessor to Linux and that they share an identical security model. To be fair, Unix wasn't open source, but I stretched the truth less than the open source guys, so I didn't feel too bad (Unix was "source available" at the very least  : )  And finally, I let the committee know that open source didn't mean open standards or open data formats and that, in fact, those were things that commercial software companies had done the most to bring into greater use over the years.

    Having never done anything like that before, I wasn't sure how well I'd done, but one of my fellow panelist (a procurement officer from another giant suit-wearing organization) wrote "nice job" on his pad of paper while his colleague preached the wisdom of "amending the language" of the bill to be more "practical."

    At the end of the hearing, the chairman of the committee called out some names of the most credible, suit-wearing fellows from each side of the debate to form a working group to come up with a bill that the committee could actually consider submitting for a vote. The sub-text was that the bill as it currently stood was pretty silly; it didn't allow any greater freedom to pick open source software but it did limit the ability to choose proprietary software, which wouldn't make those Oregon software company tax payers happy. This seemed a most sensible conclusion to me and gave me confidence that our government isn't so screwed up after all.

    When the room was cleared, I was assaulted by one of the open source proponents, reminding me that Unix wasn't open source and that Linux would never have any such problems (which makes the presence of virus protection software for Linux seem like a very poor business decision). I was also cross-examined by a tall, thin, balding, old-ish man with the longest grey beard I've ever seen in person. He seemed very knowledgeable and was very interested in the details of my opinions. He reminded me of nothing more than a fallen Richard Stallman in 30 years and added to the surreality of the morning.

    On the way back to our cars, Mike thanked me for coming and asked if I was glad that I'd come. It surprised me to learn that I was. Not only did I feel that my "just a guy" presence helped the suits make their case, but I felt like I was doing my duty as a citizen. Who knows, this experience might bring out the politician in me. I'm sure I could do at least as well as Jessie Ventura. : )

    Microsoft & Patents

    Tue, Feb 18, 2003

    The buzz was all around VSLive last week about Microsoft patenting the .NET Framework API. In fact, an eWEEK reporter asked my opinion and this is what I said:

    I'm no patent attorney, but in examining the patent application, it looks to me as if they're claiming a patent for the entire .NET Framework, which comprises the classes that a .NET programmers uses to get anything done. My understanding of the patent laws says that Microsoft has every right to do this, since they invented it. The reason for them to do this is so that they can maintain control of its implementation. Hopefully Microsoft will grant a royalty free license to all implementations of the CLI ECMA standard, which makes up a large percentage of the .NET Framework, or that standard will be worthless.
    Even if they grant such a license, projects like Mono are still vulnerable. They plan on implementing even the parts of .NET that aren't standardized, like ASP.NET and WinForms. This would allow Windows programs compiled against .NET to run under Mono on Linux, providing a single API for cross-platform applications. This has been tried and failed in the past as recently as Java, but I had hoped that the Mono guys could make this work. When Microsoft is granted this patent, they can shut down the non-standardized parts of Mono whenever they want. That's good for Microsoft share holders, but it's not good for 3rd party developers that want to write cross-platform solutions.

    What I should have added is that as far as I know, Microsoft hasn't ever enforced its patents. Apparently they keep them for defensive reasons only. Or, they could be waiting 'til they have a critical mass of patents, enforce them all at once and win the game of Risk that they're playing with the world. : )

    Saving Your Career

    Fri, Feb 7, 2003

    In response to Never Send An Email In Anger, Lars Bergstrom recommended that I set up a rule that defers sending an email for 1 minute. I set it for 2 minutes under Outlook XP like so:

    • Tools->Rules Wizard
    • New
    • Start From A Blank Rule
    • Check messages after sending
    • Which condition(s) do you want to check? -> None
    • This rule will be applied to every message you send. Is this correct? -> Yes
    • What do you want to do with this message? -> defer delivery by a number of minutes
    • a number of minutes -> 2
    • Finish

    And it works like a charm. It's always w/in the first second that I wish I could recall a message, so two minutes should be more than enough. Wahoo!

    Let The Language Wars Continue

    Feb 3, 2003

    A friend of mine pointed out to me the other day that the C in CLR stood for "Common," that is, the CLR provides the same services to all languages. In fact, at this date, C# and VB.NET are really just "skins" over the CLR and provide nearly identical functionality. With that in mind, why are we still fighting the language wars? There are several reasons:

    • VB and C# programmers are just culturally different. They come from different backgrounds, different educations and different points of view. Remember that VB was initially invented to let non-programmers program. C++ programmers came from folks building operating systems. Those roots are still evident today.
       
    • The VB and C# product teams are different and gain benefits based on how many of each kind of programmer there are. Based on that, do you think that those teams are going to pound the "all languages work great under the CLR" or the "C#/C++/VB.NET rocks" drum? Which message makes you look best at review-time?
       
    • Languages *should* be different. Managed C++ does that cool managed code/unmanaged types thing. Eiffel# does Design by Contract. Perl.NET has obfuscation built in at the source code level, alleviating the need for a 3rd party tool. The fact that VB and C# are virtual clones of each other is a mistake that I hope is rectified. Frankly, I hope that VB goes back to it's roots of enabling non-programmers, as that's a huge hole in the current list of managed languages. Certainly C# is going back to its roots by adding generics et al in the next version.

    I've found that the "Common" means that teams can use the same language at more levels of their system, i.e. no more VB for this, C++ for that, script for this other thing. Now it can be all VB or all C# (or almost all, 'til Yukon ships) and the number of different kinds of programmers needed for a single project goes down. That provides a real benefit to companies trying to keep costs down and quality up while still allowing the team to decide what language features are important to them. This is goodness.

    With the increased shared capability at the runtime level, I'm actually hoping that language motivation will increase. I think that there's still a lot left to do to make the programmers more productive and the motivation for one language to gain ground over another is a good thing. Plus, I still have an excuse to make fun of semi-colon-challenged programmers and what could be better than that? : )

    OOD (The D Stands for "Dead In The Water")

    Fri, Jan 24, 2003

    Reading a very interesting book which I'll discuss in a future post, I came to a startling conclusion. As much as I love OO thinking and programming, OO databases are never going to fly. I realize that this may not be so startling considering how long OOD products have existed and how unsuccessful they've been so far, but the conclusion I came to was *why* they'll never fly. The reason is simple: the data itself is more valuable than the programs that use it.

    For an OO guy, taught that behavior was everything and data was an implementation technique, that's a startling conclusion. However, the beauty of a database is that it's devoid of behavior, or, if there is behavior, it's layered in on top of the data. Programming languages come and go along with the ideas that underlie them and the applications that are built with them. Relational data, on the other hand, is a model that's simple enough, but complete enough, to move forward from application to application, accumulating value as you go in the data itself. And, since the relational model is so entrenched, no technology for the last 10 years or the next 1000 would be complete without support for it. Even Microsoft, IBM, GM and AT&T will prove to be less enduring than relational data, the tools to program against it and the tools to slice and dice it w/o programming anything (the latter are amazing strong already and continue to grow).

    Data in OO databases, on the other hand, are bound to behavior and worthless for anything but the limited set of applications for whom the behavior was paramount and the data an implementation detail. When things change, as they always do, how are you going to get the data out so you can do things different? You're going to dump it to the simplest, most complete, most firmly entrenched data format that the world has every known -- relational data.

    OO persistence formats are, by their natural, tied to a specific object model and therefore hopelessly proprietary. And with the emergence of XML, OO persistence formats are going the way of the dodo, even for applications running on machines without a database server. Why would I persist data to a closed format when I can choose relational data for the big stuff and XML for the small stuff? Both provide endless tools for slicing and dicing and bringing forward when the application dies. With OO persistence, when the app goes, so goes the data. The problem with OOD is that things are *too* seamlessly integrated. Ironic, no?

    Discuss

    Sealed Sucks

    Thu, Jan 23, 2003

    I've come to the conclusion that the use of the "sealed" keyword in C# (and the concept in .NET) should almost never be used, at least on a class. Semantically, sealed applied to a class means that a class cannot be used as a base class. For example, the ImageList class from the System.Windows.Forms namespace is sealed:

    public sealed class System.Windows.Forms.ImageList : ... { ... }

    What sealed means is that the designers of the ImageList class didn't take the time to test what would happen in all the scenarios where an ImageList is specified but a subclass is provided, e.g. MyImageListEx2. So, since they didn't test these scenarios, they're protecting developers from deriving from the ImageList base class when bad things might happen. They're also protecting developers if the base class changes radically in the future and derived classes no longer work.

    Stop it!

    I don't want to be protected in this way! Instead, I want to try to derive from ImageList and see if it works in the scenarios in which I'm interested. And if future versions of the ImageList base class break my derived class, I want to update my derived class in ways that work across versions of the base class or have two versions or whatever else I need to do to make it work. By making a class sealed, I just don't have any choice in the matter, which severely limits me in what I can do.

    As an example, I think that the current ImageList implementation sucks in the following ways:

    • Every time you need to edit an image, you need to remove the old image and add it back again
    • Images are too small to see what they are
    • Can't tag images with names

    So, I'd like to build my own ImageList implementation that has the exact same programmatic interface, but that pulls images from manifest resources, fixing most of the issues above. All of the controls that take images get them from an ImageList type, so I need to provide my extra functionality in a type that's compatible with ImageList. However, the only way to do that in .NET is via inheritance and the damn sealed attribute disables my ability to do that! Instead, I have to build a custom component that's also an extender provider if I want to provide the same design-time usage as an ImageList and I have to tell developers using my image list component not to use any of the ImageList-related properties because it will conflict with mine. I literally can't package my functionality in a way that's developer-friendly in the same way as the ImageList and it's all because it's *sealed*!

    Of course, the ImageList class isn't the only one. I had a solution to the problem of asynchronous method calls to web services from WinForms apps the other day (the problem is that an extra hop is always required to get back to the UI thread), but my solution can't work because the base delegate type required to make an asynch call is sealed. And the list goes on and on of things that I can't do because somebody is "protected" me from potential bad things.

    Please, please, please, please, please don't mark your classes sealed. If you do, folks that want to provide extended functionality, and test to make sure that it works the way it's supposed to, don't even have the option. Type compatibility is a huge deal when you're dealing with class-based abstractions instead of interface-based abstractions and using the sealed keyword throws all of that away. The C++ community survived very nicely without sealed for a decade and it's made half of the classes on my site possible.

    You took away my deterministic finalization. Must you also take away my ability to derive?

    Discuss

    New Year's Resolution

    Wed, Jan 8, 2003

    I just flew in from 2002:

    and boy are my arms tired! Even I look at that list and think "holy workaholic, Batman!" Of course, I couldn't have done all these things alone. I worked with fabulous co-authors and co-contributors. Thanks to you all and I look forward to working with you again in 2003!

    In the new year, I have the following goals:

    • Make Ask The Wonk a fun experience for all involved (it just started on Monday, but it's already great fun answering the level of questions I've received!)
    • Move the DevCons to the phones via the PhoneCons to avoid the expense and hassle of travel for everyone, while still maintain the power and charm of the DevCon
    • Get those .NET War Colleges humming! I *so* look forward to these
    • Several more releases of Genghis (a new release is already cooking)
    • A few more magazine articles (I've got a few already in the queue)
    • Finishing up the Rotor ref-counting project, publishing the code and the results
    • Re-org the web site a bit (again!)
    • Continuing the Wonder of Windows Forms column
    • Hanging on the Off Topic mailing list (still my favorite mailing list)
    • A couple of other projects that I'm dying to share with folks, but am sworn to secrecy...
    • Losing another 35 pounds (it's a 2-year plan)
    • Find a way to take a vacation

    We'll see how I do this time next year, especially on those last two.

    Discuss

    Apps Are People, Too

    Thu, Jan 2, 2003

    I concerned Wahoo! patron sent in the following screen shot of the current high scores as exposed by the high scores service:

    As you can see, the high scores service has turned into the poster child for the need for web service security. However, after hanging out at two Web Services DevCons and talking with Keith "Mr. Security" Brown, I've come to the conclusion that there is no good way to secure this specific web service. Even worse than that, there's an entire class of web services just like it that can't be guaranteed secure.

    The goal of the high scores web service is to provide access only to the Wahoo! app itself. Only Wahoo! knows when someone has earned their score while playing instead of merely faked it through some other means. Of course, this application is just for fun, so the lack of a secure high scores repository is hardly a big deal (although I'm often surprised when people tell me that they play wahoo.exe instead of sol.exe). However, imagine that a real application wanted to do the same thing. Maybe Microsoft only wants Office applications and not Linux knock-offs to query the clip art web service on microsoft.com. Or maybe your business wants to provide a web service that only your apps can talk to.

    Of course, Microsoft doesn't ship the source code for Word and your business is unlikely to ship the source code for your apps if you plan on making money on them (remember actually making money on software?), so that's different than Wahoo!, isn't it? No. Every time you put code on a machine outside of your sphere of influence, you might as well ship code, especially if it's .NET code, which comes with a built-in disassembler! "But wait," you say. "What about code obfuscators?" Well, that arms race has already been fought in the world of Java and disassemblers won. There was no way that an obfuscator can hide the details of Java byte code without completely destroying the usability of the code (particularly in the area of performance). .NET will be no different.

    "Aha! But what about unmanaged code? x86 can't be read like IL." You're right. It is harder to disassemble x86 than IL, but not significantly so. The x86 disassembler tool vendors have been working for a lot longer on this problem and we've bred guys like Andrew Shulman and Matt Peitrek that dream in x86 and only translate to English as a convenience for their wives.

    The bottom line that if you ship code, you might as well ship the source, as it's available anyway. If a computer can execute your code, somebody can read it and pull out the details of whatever you're using to obfuscate the communication between your code and your back end (whether it's a web service or not).

    "So why do I have to log in all the time if there's no such thing as security?" Well, it's not as if there aren't ways to secure systems in the world, but all working security thus far invented depends on physical security, whether it's the private part of a key pair secured in your safe or a password secured in your brain. The reason that applications can't make use of this kind of security is because they don't have access to safes and their minds can be read much more easily that those of humans (although a rubber hose is just as effective as ildasm.exe, when something is really important).

    So what does that mean for applications that want to make use of back-ends? I see four solutions. One, you can tie security to a user instead of an application. For example, if I make everyone sign up for a Wahoo! account to log high scores, I'd at least know who to ban from use when they faked impossibly high scores. However, it also opens up the possibility of the user completely bypassing the application altogether, including any checks that the client may make on validity of the data being sent to the back-end.

    The second possibility is to make things hard*er* on the potential hackers. Keith summed it up nicely:

    "After looking at your JPG, I'd suggest some server side filtering. Limits on user name length and content would help you at least reduce the amount of space that hackers can use for advertising. OTOH, you've got a nice little bulletin board going there ;-)"

    Anything I do in the way of encryption and obfuscation between the app and the back-end will slow down potential hackers and for something like Wahoo!, I don't suspect it would take much to keep folks honest (turning off the asmx test page would be a good first step, for example : ).

    One way to make things harder, and a third way to secure apps, is a dongle, which adds new hardware to a machine along with the software. Unfortunately, a dongle could be reverse engineered just as a hunk of software. It's only the fairly uncommon use of dongles that keeps them from being broken more often.

    The fourth option, which Keith mentioned, is Microsoft's new Palladium platform, which operates with special hardware and software to limit a user's access to their own computer, kind of like a universal dongle.

    The real question is, what's secure enough? Unfortunately, this is an arms race that will eventually be won by any hacker with enough smarts, time and money. For users, we continue to make things harder on hackers as we transition from passwords to biometrics and smart cards. For applications, we've got dongles and precious little else, which makes it darn hard to treat apps like the independent entities into which they're evolving.

    Discuss

    Keep On Cookin'

    Fri, Dec. 20, 2002

    I got a very nice email today from Ross Lambert:

    "I'm a new fan of yours, both in terms of your technical abilities and the down-home honesty of your columns in The Spout. I loved 'Of Eggs and Omelets', mostly because I could identify with it. My own career has been littered with a lot of broken eggs. I ran my own little software company for nearly 10 years, writing and selling developer libraries for Macintosh developers. Needless to say, the ups and downs of that market were fairly impossible to survive.

    So now I am enjoying the Dark Side, as Mac folks would say. I'm a total .NET-head, hence my fairly recent acquaintance with your work.

    Anyway, all that to say 'Don't let the turkeys get you down.' I was a pretty decent marketer; I still write ad copy for different folks from time to time. It was the only way I could manage to survive as long as I did. For what it is worth, I think your approach is innovative and fun. A few anal people will object (it sounds like they already have), but I've come to the conclusion that about 2% of the population actually enjoys being uptight and offering angry complaints. You'll never make those folks happy, and it is just as well to give them a reason to bail out early in the game."

    Thanks for that, Ross. While Of Eggs and Omelets speaks of breaking eggs as metaphor for the negative feedback I've gotten from my recent series of marketing-related emails, in truth only a tiny fraction of folks complained. In fact, almost 10% of my newsletter subscribers responded to my inquires in some positive way, which is about 50x the number of people that had something negative to say. According to the marketing guy, getting a 10% response was about 3x what he was hoping for (although he didn't tell me his expectations until *after* the results were in... : ). Even more telling was the large number of people that actually thanked us for asking. Apparently expressing interest in their wants and needs was unique for a surprising number of people. Further, the shear number of people interested in the various ideas we proposed (like the .NET War College and the WinForms PhoneCon) was only overshadowed by the number of people with good ideas that we didn't even think of (which is what lead to Ask The Wonk).

    So, while I may have broken some eggs, and every one of those emails physically pained me (how do spammers do it?!?), Ross and tons of others have encouraged me to keep on making my omelet.

    Discuss

    Of Eggs and Omelets

    Tue, Dec. 10, 2002

    My life has been one long series of experiments. I tried to be a know-it-all jerk in high school and found that this tended to cut into my social life (drastically), so I stopped (or am still stopping, depending on how well you know me : ). I tried to be a "ground floor" employee for a small company, but that stopped being fun when the repetition and bureaucracy hit and it became clear that any profits that might someday happen would be kept at the owner level. I tried being an employee for a large company, but when my projects started getting axed based on political winds that, as a low-level grunt, I had no control over, I went looking elsewhere. Then I found DevelopMentor. The combination of working on lots of different things with lots of smart people was something that I loved more than anything I've since found.

    But even that didn't stop my experimentation. After teaching and consulting for a while, I decided that instead of just talking about building software, that I would take one of my ideas and build a software development team. There I worked to build the best software development team that I've ever had the pleasure to work with and a learned a *ton* along the way. However, the fact that the product itself was a commercial failure didn't make for lasting employment.

    So, late last year, I started another whole series of experiments, this time aimed at making myself solvent as an independent in a down economy. I've been doing all kinds of crazy things to see if I could use them to help build my brand, my business and my customer base. Some of them have been critically acclaimed and a few have even been commercially viable, at least to the point that I can continue to pay my mortgage (many of my friends weren't so lucky). I have been successful in that I've gotten to do a lot of cool things and work with a lot of smart people.

    However, what I've found is that to remain independent, I have to spend a lot more time doing promotion and marketing, which goes against every fiber in my being. The problem is, although I've experimented a bunch, especially as related to this year's DevCons, I don't have any natural marketing aptitude and I don't know where to turn for help. So, I fall back on my old standby -- experimentation.

    Over several years, I've experimented with several sales/marketing/PR folks and organizations and so far, haven't found what I'm looking for as far as "mentors" go (to be fair, my standard for comparison includes Don Box, Tim Ewald and John Robbins, so I'm not surprised I haven't found someone to meet that bar). Even if I did meet that person, or may have already met him/her, I don't know that I'd recognize it. I just have no standard for comparison. With software, it either works or it doesn't. With marketing, did it succeed or fail because of the quality of the product or the quality of the marketing? The whole thing is too damn squishy and it drives me nuts!

    My most recent set of experiments is to let a friend of mine, a long-time marketing guy that I've known for years, run rough-shod over my newsletter subscribers, asking them all kinds of questions and for their help in various ways, offering my money and my time as incentives. Will it work? I have no idea. Is it risky? You bet. I've lost a dozen or more subscribers and who knows what some people think of me now that I've let marketing ideas into what I do (and I'd like to apologize again to the folks that I drove away or offended in this most recent campaign). Is it worth the risk? Yes it is, but not for the promised return (I still think my marketing friend was on happy pills the day he quoted his marketing targets). What makes it worth the risk is that I've identified a weakness in myself and I'm willing to perform the experiment and make the mistakes to see if I can come out better on the other side. Even if I fail, I've learned something. Eventually, I'll get that omelet made, no matter how many eggs need breaking.

    And to those of you who suffer with me through my experiments, thank you very much. You have no idea how much you mean to me.

    Discuss

    My Coding Standards

    Wed, Nov. 27, 2002

    Sometimes it's like I'm a war veteran in my head. I'll be going along, minding my own business, when *bang*! out of nowhere, a flashback from my days as the director of a software organization hits me right between the eyes. When it happened today, I thought it would be therapeutic to talk about it instead of trying to bury it when these "episodes" intruded on my normal life.

    The nice thing about setting up your own software organization is that you get to set your own rules, and this time "do it right." I had always planned on getting my engineers together one day and coming up with a common coding standards document, just like every software organization had, but in the interim, we started with this one:

    1. All code will use spaces instead of tabs.
    2. All new code in an existing file will match the existing style.

    Rule #1 nicely handles the case where different editors expand tabs to different spaces, causing code that was easy to read when it was written to go all crazy. Rule #2 says not to waste time reformatting existing code into your own style, but to mimic the coding style that was used by the original author. Rule #2 had the unexpected side effect of helping developers get into each others' heads, which helped transfer knowledge between us. I personally learned a bunch of cool tricks by fixing bugs in files in the style of the original author.

    After a few attempts at adding other, more traditional rules to this short list, like where the braces go and how to name variables, we couldn't find anything that was worth ruining the simplicity of our two-rule coding standards with, so that's what I've used ever since. One other benefit of this simple set of coding standards was that it left us all kinds of time to debate the merits of various text editors, which is an argument that won't be solved until just after the Christianity vs. Judaism debate is ended...

    Discuss

    Hierarchy Doesn't Scale

    Sun, Nov. 11, 2002

    I was just chatting with a friend of mine and he said that he really wanted to write a namespace extension so that he could expose a hierarchy of data in the shell. Back when namespace extensions were introduced with Win95, I thought that everything could be integrated into the shell, making the shell the last application. Sometime in the last seven years, I've come to hate that idea. As a hardcore computer geek, I've embraced the hierarchy organizational styles in three major applications:

    1. Email folders (I keep things filed in a multi-level hierarchy and use my Inbox as a to do list)
    2. The file system (I keep things filed in a multi-level hierarchy and use my Desktop as a to do list)
    3. Free-form outline program (I keep things filed in a multi-level hierarchy and use a file called todo.txt as a to do list)

    As anal as I am about arranging and categorizing things into their various hierarchies (and as many places as I've spread my to do list to, apparently), the hierarchy only helps me about 50% of the time. I spend just as much time searching for things as I do going right to where it "should" be.

    The hierarchy used to be lots more helpful, but as the data I keep around grows over the years, it becomes less and less possible to remember where something really "belongs" and to find it there. In fact, I've come to believe that a hierarchy is a terrible way to keep data organized at all. A hierarchy is really just a way to associate key words (called "folder" names) with hunks of data (called "files") and then only showing them in a very limited way. Searching is a possibility, but it either takes a long time (because file indexing is turned off) or it misses files (because file indexing is turned on -- what's with that, anyway?). Searching creates an ad hoc logical folder, but there's no way in the shell to create a permanent logical folder with custom content.

    The basic hierarchy structure is easy to understand, but things become much more powerful if I can keep one hunk of data in multiple locations. Some versions of the Windows file system support this , but the shell doesn't (although it can be simulated with shortcuts). Also, the same kind of "pivot table" capability that Excel provides, mixed with a much faster, more flexibly searching capability of a database, is much closer to what I'm after. Hopefully Longhorn will provide something like this.

    Also, being able to search all three of my hierarchical  data sources at the same time would be pretty damn useful, but one thing at a time...

    Discuss

    A Giant Sucking Sound

    Sat, Oct. 26, 2002

    While I'm in favor of NAFTA, and free trade over all, it's certainly not helping US workers. Instead, it favors US corporations as they made use of cheaper labor. Of course, it's the corporations that also seem to make out on these deals, doesn't it? Similarly, the other "giant sucking sound" I've heard lately are my friends moving to Redmond to work for Microsoft. MS is using the recession to cherry pick the best and the brightest in the industry. I can think of almost ten people I know personally that have gone to Microsoft in the last six months. And these aren't folks that were laid off and had to go, either (even though everyone but Microsoft is laying off). These are good folks that had good jobs, either as employees or as independents. One even owned half of what was my favorite company in the whole world! So why are they doing it? Why are they giving up their old lives to work at MS, often moving to Redmond in the process?

    I think they're going for a variety of reasons. One is definitely the safe harbor aspect. As an independent in the current economy, I have to work my butt off to attract funding using self-promotion techniques that I didn't have to use during the Internet boom. I'm successful and I love the work and the life, but it's still a lot of work that I know others are not willing to do. Another reason related to the "really hard work" problem is that Microsoft, for the caliber of my friends, is allowed to offer what used to be a laughable salary, but is now looking pretty good against what's generally available. If you can get 75% of what you used to make as an independent, great benefits and stock options that may do something someday, that's pretty compelling. And the stock price is pretty attractive right now. It's my belief that, as a government-sponsored monopoly, Microsoft is fundamentally sound, and the stock price is artificially low. If you were going to go to Microsoft any time in the last five years, now is the time. The stock is only going to go up.

    But the big reason that makes people go, and this is the one that might tip me some day, is the raw, visceral experience. For better or worse, Microsoft is the mother ship from which everything we know now has sprung. And they're still setting the tone. I know I dream of moving to Redmond to work on the next technology that's going to kick ass in 2-3 years, like Don and Martin and Yasser did. I'd also love to live where I am now, commuting to Redmond a week/month to work with developer education, focusing on research and writing, like Tim did. Sometimes I want to just chuck the extra effort it takes to stay "outside," throw up my hands and let the assimilation process begin.

    So, why haven't I thrown in the towel? I'm waiting. I'm waiting for the perfect balance of quality of life where I get to spend every day doing exactly what I want, working with a team on a long-term project that I really believe in, but without the politics or the management responsibilities that I deplore and without giving up my family or dropping significantly in income. Right now I've got that all nailed except for the team and the long-term project, so I've got it damn good, but I'm still looking. Who knows? Maybe I'll get caught in the mass geek migration to Redmond some day, but not yet...

    Type Safety in a Loosely Coupled World

    Thu, Oct 17, 2002

    Tim Ewald gave a very rousing keynote address at the WinDev conference in Boston yesterday. During his talk, he did something I've never really heard anyone do convincingly before -- he defended the typeless recordset/rowset/dataset style of programming. His justification was that you don't always need type-safe object models and, when getting a subset of data, they're often more trouble than they're worth (do you really want a set of types for every query in your app?).

    My standard objection to the "just the data, ma'am" style of programming is that I don't get compile-time type checking. Of course, I can write the code to check all the data I get at runtime, but I don't like to do that. Instead, I like things like the type safe dataset generator built into VS.NET. However, that damn tool fooled me. I looked at those type safe wrappers and considered that compile-time type checking. Of course, it's not. Instead, it's a hunk of code that pretends to offer compile-time type checking, but only really offers run-time type checking, because the data still needs to be coerced at *runtime*.

    I have always turned up my nose at run-time type checking until I realized (and this is the insight I got from Tim's talk) that *all* marshaling-based type checking is done at run-time. Even the type-checking done in COM between apartments needs to coerce the data to and from a serialized format, which means that it's possible for the data to be mismatched between two endpoints, causing a type exception at runtime. Since I'm not willing to give up the loose coupling involved with components talking to each other across apartment/thread/process/machine/context/appdomain/whatever boundaries, I need to accept the fact that type checking needs to happen at run-time as well as at compile-time. As far as type checking is concerned, unmarshaling an RPC call stack is really no different than coercing/converting dataset columns or applying an XSD to an XML document.

    Once I've accepted run-time type checking, I can take Don's advice to "free your mind" (he's moved on to other parts of The Matrix not involving medication) and embrace things like structural typing, which is much more flexible than the nominal typing that OO languages rely on. I told you that "nobody makes it the first time," Don, but I think I've finally made it across. : )

    The Fallout Begins

    Wed, Oct 2, 2002

    Two months ago, I noted a fall in morale in the IT industry amongst my friends and colleagues. I wondered whether the best people in the industry who'd been fighting for a sane development process, but living without it because people were handing out cars as signing bonuses, would rather not work in another industry when the cars were no longer available and the fight for what was right didn't seem to make as much difference any more. Yesterday, one of the people that I'd put into the "right up there" category, Justin Rudd, announced his intention to pack it in and go back to school to be a doctor.

    This kind of thing shakes my own faith. Should I continue to bust my hump on the latest and greatest technologies or ditch it all and start that novel I've got in the back of my head? I still really love doing the former, but it seems that everyone has to work a lot harder for a lot less these days. Maybe I just need to readjust my thinking, but damn, being smack dab in the middle of an economic boom really does a number on you! I feel like the guy who found a silver mine in the middle of the gold rush. I don't have any trouble feeding my family and it's not fool's gold, but I still pine for those deep, yellow nuggets...

    Never Send An Email In Anger

    Fri, Sept 13, 2002

    I learned how to write good emails at the foot of the master -- Don Box. Whenever we'd decide we wanted something, he'd grab his computer and say, "Let's write the email" and it would be done.

    One of the most important things that I've ever learned about high-tech communications is to never, ever write an email in anger. Or, to be more precise, never *send* an email in anger. I encourage you to actually write it. It always makes me feel better. But don't address it, because you want that email to first end up in your Drafts folder and go from there to your Deleted folder. If you address it and mean to press Ctrl+S to Save but manage to press Alt+S to Send by mistake, you might well be looking for work in another industry. If you don't address it, however, Outlook complains and you can breathe a sigh of relief. Frankly, I wish there was an add-in that protected me even if I ignore my own advice:

    Of course, this spouting could only occurred after I've violated my own advise, as I've often done over the years, always to my determent. When you're angry, all you care about is making sure that your anger comes through. If I give myself an hour or two to think on it, when I come back to read that angry email, it always makes me flinch. Writing an email once I'm done being angry always yields the nicest, most thoughtful emails that I can write. Those I find to be *much* more effective.

    Attracting and Keeping Good Folks

    Wed, Sept 4, 2002

    A friend of mine requested an essay on my thoughts of attracting and keeping good employees. I've had the privilege of working with some of the best and the brightest over the years and seeing how companies hire and keep them. My take is that companies that attract the best do so with a reputation of excellence. As one example, Google has kick-ass technology, so I'm sure most of you want to work there (I know I do : ). On the other hand, there are plenty of companies that have a reputation for buggy, unusable software that turn us off, all without ever hearing about the salary and benefits package.

    If you can attract good folks, you'll also attract lots of mediocre folks and some not-so-good folks. There are all kinds of ways to screen these folks out. My favorite is to ask them "why?" questions. If they can tell me the name of the operator that appears as a colon between the last paren of a C++ constructor signature declaration and the opening curly place, that's great. But if they can tell me why C++ has it, and why Java and C# doesn't, they're hired. Of course, I let the interview candidate pick their own area of expertise and ask them questions about what they know best to see how deeply they've gone in their explorations. The ability to figure out the "why" is a necessary skill for folks that you're going to trust to take vague requirements and come up with Google-like results in an environment where no two consecutive projects use the same set of technologies (or even similar ones, increasingly).

    To select for personality, as well as technology, I like to whip behavior interviewing questions on folks. Instead of sketching a situation for an interviewee, e.g. "how would you deal with conflict in the work place?", behavioral interview questions ask people to remember real situations they've been in and how they reacted, e.g. "Imagine a time when you had conflict in the work place. How did you handle it?" Everyone knows the right way to handle conflict in the work place, but far fewer of them have handled it properly when it actually happened. The idea of behavioral interviewing is that past behavior indicates future behavior, so if you don't like that your candidate punched his last manager in the nose, that's something to find out up front.

    Once a good person has been hired, keeping them is a matter of paying them what they're worth, letting them do what they're good at, helping them get better at what they're not so good at, making sure you don't waste their time on stuff that doesn't matter, showing appreciation for a job well done and otherwise staying the hell out of their way.

    Development for Developers

    Fri, Aug 30, 2002

    I got an email today from David, who says, "So, I am looking to see what I can do to develop my skills as a designer. The trouble that I have, is simple. Where does a programmer that is over 40 years old, with a good job, and a good family turn to to learn something like this?"

    David, developing in any career means taking risks, trying new things, making mistakes. Some specific things you can do to improve your developer/designer skills include:

    • Examine your goals. Do you want to be a better coder, a better designer, a better tester? What's better to you? Fewer lines of code? More lines of code? Faster code? More readable code? More documentation of code/design? More thorough designs? More testable code? More unit tests? Set yourself a list of goals and examine it on a regular basis to keep yourself on track.
    • Read some books and articles, like Writing Solid Code, and re-write some of your own code using the techniques you've read.
    • Pick your favorite feature in your favorite application. Design it. Implement it.
    • Read and review other people�s code to see what they do, especially in languages and task you're unfamiliar with to get a different point of view.
    • Pick a bug out of the bug database. Find the real cause. Find the implementation mistake that caused it. Find the design mistake that caused it. Change the implementation and/or design to find other similar bugs in your code base. Change the design/implementation to make similar bugs impossible in the future.
    • Run a code review to get your peers' feedback on your code.
    • Get together with a group of developers at your job for weekly lunch lectures. Teaching someone is a great way to learn.
    • Take the time to really do something "right." You can't always do this due to other real-world constraints, but if you never do it, you're much less likely to get things right in the future.
    • Take the time to follow your "fetishes." I can't tell you how often I've followed up on something that didn't have anything to do with what I was doing, but I just couldn't leave it alone, and then it dove-tailed with something else I needed to do almost immediately. Most of this web site is a result of following this advice.
    • Attend a conference and ask a lot of questions. Really drill the speakers to make sure you "get it" (especially if it's me : ).
    • Write an article on something and send it around to your peers or put it up on the web. Writing about something is the only thing I can think of that's better than teaching as a way for you to learn.
    • Hang out on the mailing lists and news groups, but only answer questions you don't know the answers to. Don't worry about being wrong and thank everyone who shows you when you are.
    • Write a hunk of freeware/shareware/open source software and put your software up on the web along with an installer and documentation. Maintain it.
    • Find yourself a mentor. Ask lots of questions and get them to review your work. I've had a number of mentors of my own over the years (Mike Woodring, Paul Crutcher, Don Box, Tim Ewald, John Robbins) and it's made a world of difference.

    If you'd like some "hands on" guidance to improve your skills as a developer, I'm available as a mentor. I've mentored a number of folks over the years and they've had some nice things to say about the process. But don't feel you need me to take advantage of these tips. Take risks, try new things, make mistakes.

    Newsletters Are Hard!

    Wed, Aug 28, 2002

    As I write this, several thousand emails are being sent to the initial list of SellsBrothers News newsletter subscribers. My motive (to let folks know what was happening on the site without having to visit every day) was pure, but if I would have know how hard it was going to be to set the thing up, I don't that I would have started.

    It began with a simple form on the web site to take people's email addresses, which were in turn emailed to me and sorted into a Outlook folder. When that reached a couple thousand without yet having sent out a single issue, I figured it was time to put it into a real database. So, which a bit of data cleaning through VS.NET and Excel to get the dates right, I plunked it into an Access that would serve as the repository on my ISP-managed site. That was all fine and dandy but for one problem: I had to send emails using the data from my own machine, not the machine with my live site (and therefore the latest subscriber data). Did I really want to download an Access database from my ISP every time I needed to send a newsletter? It won't be often, I admit, but that still seems wrong, doesn't it?

    So, I paid the extra $10/month to get SQL Server support on my site and worked with a friend of mine (Paul Crutcher) to build the form to take name, email address and HTML vs. Text settings. Except it's not just one form. To make sure that folks aren't subscribing other folks, we send out a confirmation email with an URL in it that updates the database and shows another form indicating whether that worked or not. Then, in case anyone changed their mind, we needed another form to change subscription settings along with another form letting them know that their changes were made. Of course, before we could let them change their settings, we needed to let them log in, which was another form. And, if they forgot their password, they need another form so that they can enter their email address and we can send it to them. Further, if the worst happens and they tire of my musings, they need to be able to unsubscribe themselves.

    Not only did Paul build all of these forms, but he built them in two parts, a form part and a control part, so that I could update the form part to have the sellsbrothers.com look 'n' feel, while leaving the real logic in the control part untouched (and potentially reusable). All in all, just letting folks manage their newsletter subscriptions was 46 hunks of HTML packaged as .htm, .aspx and .ascx files. 46! I would have downloaded something and integrated it, but I never found anything to do the job (and this is where I get a hundred emails showing me the error of my ways... : ).

    Of course, all that user-managed subscription work was to avoid one thing: angry emails. I didn't want folks who'd forgotten they subscribed many months ago or, worse, folks that were subscribed implicitly from other activities like the DevCon, to find themselves on a list with no way to get off of it except for sending me angry emails. That's just how insecure I am. : )

    So, after a few weeks of Paul and I working on the pages to do the administration for me, I thought that the hard part was over. I was wrong. While I did have an SQL database on my site, it was still nearly empty. There were some folks who were newly subscribed after the new code went live, but all of the folks who'd subscribed before then were stuck in an Access database. "That's OK," I thought. "SQL Server and Access were made by the same folks. I'm sure I won't have any problems moving the data." That was two weeks ago. It took tons of advice from my database friends (thanks BobB and ShawnW and BrianR!), along with a final push from my brethren on the Off Topic Mailing List to get the data moved to the right place. The good news is that I got to polish my T-SQL skills a bit and I got to play with DTS and the Enterprise Manager (both very nice pieces of software).

    But that's not all. Once I had the subscribers in the database, I then had to send several thousand emails, sorted into folks that want HTML and folks that want Text, keeping track of bad email addresses. This time, I went looking for a commercial product to do the job. I figured that since my inbox was full of spam (SpamNet is my new best friend!), that there must be really great tools for sending emails by the boatload. And again, my friends on the Off Topic mailing list were there to help with a recommendation of the Advanced Direct Remailer. ADR is also a nice piece of software that comes out of the box configured almost right, but not quite and the documentation has to be read very carefully. ADR is an SMTP server that takes mail from your mail client and forwards it to a list of folks based on who you sent it to. For example, you can send it to foo@localhost where "foo" is a mailbox that resolves to a list of email addresses in a text file or you can send it to bar@localhost where "bar" is a mailbox that resolves to a select statement from a database. That all works great, except if you get any of the settings at all wrong, ADR starts acting like a real email server and just tries to send the email to foo@localhost. Well, actually, it can't be foo@localhost for me, since I'm using Outlook XP, a marvel of software engineering that in it's infinite wisdom prohibits me from sending an email to a server without a "." in it. So, I send an email to foo@127.0.0.1, which ends up in ADR, but the default settings only resolve requests sent to "localhost", so ADR won't do the queries. However, it is talking to the built-in SMTP server on my machine (which I need for testing my web site before publishing it), so it looks like it's doing something, making it even harder to figure out what's going on, since I've never seen what ADR does when it works correctly.

    When I finally do get everything right and the emails are queued in ADR properly, I can tell it's going to take hours of 100% CPU utilization for the newsletter to get out, so I go on to something else. But I can't stay away for very long, so I'm constantly logging into the machine doing the sending via Terminal Services to check on the progress. With the CPU fully utilized, all the failed TS connections (I have to keep trying!) eventually crash the ADR machine, causing a panic as I reboot. I needed have worried. ADR has kept everything logged and picks up right where it left off before the crash. Truly an amazing piece of software.

    Why do I feel like Jerry Pournelle all of a sudden?

    Now, as I'm drawing this missive to a close, I'm getting half a dozen emails from subscribers that wish to unsubscribe but can't because of the peculiarities of the imported data vs. what I tested against. So, the angry emails have started. Here's a particularly angry one:

    Subject: Get me off your spam list

    You are too much of a hassle to remove, you lie about where you got my address, I do not trust you at all.

    I will prosecute you my every means possible if you do not remove my address from your database.

    If I find out you spread my address, I will go after you for that.

    Oh, well. I tried...

    The Apple and the Tree

    Tue, Aug 13, 2002

    Yesterday my eight-year-old and I had the following conversation:

    John: "Dad, do you know a lot about computers?"
    Dad: "I know my share."

    John: "But do you really know a lot?"
    Dad: "I know pretty much."

    John: "What buttons to you press to make that come up (pointing to the Start button)?"
    Dad: "Ctrl+Esc"

    John: "And how to you make it do Run?"
    Dad: "Ctrl+Esc+R"

    John: "Cool."

    Cool indeed. : )

    Industry Burn-Out

    Sat, Aug 3, 2002

    Do you feel it? I do and I know that a bunch of my friends do. The whole IT industry is in recovery from the crashing lows that can only happen after impossible highs. In recent conversations, I hear terms like "burned out," "bitter" and "jaded" coming up again and again in our conversations. Since I got into this industry just as it was idling before take off, I have no frame of reference, but I'm guessing that things will level off at a bit better cash flow than right now, but much better morale.

    The question is, how long will it take for the energy and excitement to come back? I know that I'm still healing from a three-year stint on my last big project, and even though I have an itch to try something else, I fantasize about trying my hand at another industry. I always figured that the shake-out would make the bottom feeders leave for something else, but now that we seemed to have settled on good, although not great, salaries and benefits and shaky processes at best, how many of the top folks will just bail from something else? I haven't actually seen anyone I respect leave for greener pastures, so I've got my fingers crossed that things will turn around.

    Where Do You Find the Time?

    Thu, Jun 27, 2002

    I had lunch with a couple of colleagues on the lecture circuit today and after they asked me what I was working on (Genghis, the Web Services DevCon in October, ref-counting for Rotor, a few books, some consulting, etc), they asked where I found the time. Here's how:

    1. I work with a *ton* of very talented folks. The following are just the ones I'm remembering off the top of my head that I've been working with lately: Chris Tavares, Brad Wilson, Shawn Van Ness, Jon Flanders, Don Box, Tim Ewald, all the Web Services DevCon speakers and staff, all the Genghis contributors, Tim Tabor, Michael Weinhardt, Microsoft, Dharma Shukla, Brian Harry, Chris Andersen, Mark Boulter, and, of course, all of my former DevelopMentor brethren.
       
    2. But most importantly, I don't attend meetings or request vacations or approve vacations or attend meetings or receive reviews or give reviews or attend meetings (did I already say that?) or do any of the other things that employees have to do. Skipping these activities easily doubles or triples my productivity. Of course, I had to give up the steady paycheck to make it happen and it's not the life for everyone, but it works for me just fine. : )

    Real software engineering has so little to do with actual technology, it's kinda sad. I'm lucky. I only have to do the technology part. My question is, how do people with full-time jobs find the time to learn the technology?

    XML & Inclusion

    guest editorial by Don Box, Tue, Jun 25, 2002

    Chris, I just read your "Object vs. XML" post on the spout and I'd be pleased if you would allow me to respond with my own personal spoutlet. Here goes:

    For much of the 1990's, I spent a lot of time writing COM code in C++. The combination of C++'s static type system + COM's dynamic type system was a very powerful combination that I am proud to have been involved with, even though my contributions to COM were from afar as a non-Microsoftie.

    In March of 1998, I had the pleasure of working on the initial SOAP protocol with Microsoft and Dave. That experience was a turning point for me, as it forced me to acknowledge type systems that were not part of the classic OO family that I had come to know as the "one true way."

    Unlike COM or Java, XML tends to attract developers of every stripe, each of which has a wildly different sense of esthetics with respect to language design, data vs. processing model, structural vs. nominal typing, functional vs. declarative vs. imperative styles, etc.

    Because XML's raison d'etre is interop, XML needs to be neutral with respect to these choices, otherwise, the barrier to entry becomes too excessive for some communities to participate. The current pushback against XML Schemas is a great example of this effect.

    XML Schema imposes a type system over XML Infosets that is very similar to the OO type systems you are familiar with. This makes XML Schemas well-suited for importing directly into Java or C# programs.

    Unfortunately, the XML Schema type system has features that don't make sense if your world doesn't revolve around named user-defined types (e.g., several script languages, SQL, etc.). For that reason, some members of the XML community has been lobbying for something with a looser type model than XML Schemas. Had the XML Schema working group made it clearer how to do this sort of thing with XML Schemas, I believe the time for adoption would be that much shorter.

    Getting back to your original post, I find your characterization of my colleagues and I as "so steeped in the new world that they forget where they came from" a bit misleading.

    As an XML guy, I try not to focus too much on where I came from. Rather, I try to bend over backwards to be respectful of where other people came from.

    I don't want the guy writing ML code in Dayton, Ohio to shove his world view down my throat.

    I'm trying hard to reciprocate by keeping my OO/C++/COM sensibilities in perspective.

    XML is about inclusion.

    It's the ultimate Rorschach test.

    We all make it into what we need it to be.

    That's the "secret sauce" that makes XML what it is.

    Object vs. XML

    Sat, Jun 22, 2002

    I was watching a group of folks present a new XML standard the other day and I realized something for the first time: to XML folk, OO languages are just script-like "glue" for connecting XML processing steps, the "Unix pipe" of the new millennium, if you will. Integration with OO languages is necessary to enable XML dominance, but that's an accident of history. In the view of the XML zealot, OO will eventually fall away and only pure, clean XML will be left in its place.

    As an OO guy, I find this view disturbing. As a general technology wonk who sees the value of XML, I find this view unrealistic. Just so you XML folks know, OO guys look at XML as a data transfer syntax and that's all. OO guys are happy that XML is there, but they prefer to stay away from it in favor of their nice, familiar OO environment.

    The problem, of course, is that many XML guys are so steeped in the new world that they forget where they came from. To paraphrase the Matrix, XML guys don't even see the angle brackets anymore -- they just see blonde, brunette, redhead. OO guys, of course, *only* see the angle brackets and prefer their artificial world-like simulation.

    The result of this massive gap between XML and OO folks is that the great thing that the XML guys are building, i.e. a general-purpose hierarchical data manipulation, transformation and interoperation infrastructure, something that OO guys desperately need, is being lost because the two groups don't know how to communicate with each other.

    So, to enable XML to dominate, XML folks have to be sneaky. Just like OO finally took off in C++ when it provided a super-set of the procedural programming in C, XML has to provide a super-set of OO programming, down to the easy syntax and the compile-time type checking. Only when you give the OO guys exactly what they already have can they begin to see what new things you've given them.

    Karma

    Wed, Jun 12, 2002

    While I definitely do have faith that there is a higher power in the universe (although I haven't yet decided if the universe is a good place to be or if it's just a simulation solving some higher level non-deterministic finite state automata), I'm not a religious man. If fact, I consider myself a completely recovered Catholic (I've been clean and sober for more than a decade and I never feel the need to go back for another hit off the body of Christ) [1].

    Likewise, I'm not a superstitious man. I understand that going under a ladder may cause pain if something drops on me, but not for some other mystical reason. Similarly, breaking mirrors could cut you, but only the most serious of cuts could last for 7 years.

    Still and all, I do believe in karma, otherwise stated as "what goes around, comes around." It's happened many times in my life that a lot of bad luck eventually yields to a lot of good luck. Likewise, when you do bad, bad comes back at you and when you do good, good comes back. Of course, these phenomenon can be explained by statistics and human nature respectively, but I prefer to think of a giant celestial scoreboard that I can affect by doing good for people. Or, and this happened just today, if I do something to cause harm, even if there's nothing I can do to make it up to the person involved, I often find myself feeling better if I do something good for someone completely different. Oh, wait, maybe I am superstitious... Still, I find it a comforting way to run my life, so I'm going to stick with it. : )

    [1] I've known practicing Catholics that are offended by the idea that Catholicism is a disease to be recovered from. Sorry.

    Adding Ref-Counting to Rotor

    Tue, Jun 11, 2002

    Microsoft has granted Sells Brothers, Inc. a research grant to add ref-counting to Rotor and to study the performance effects. The proposal that lead to that grant is available here. There's been a lot of speculation about just how we're planning to add ref-counting to Rotor. Here are the highlights:

    • It's not just "me," it's "we." I've already have very useful input from several folks, including Jason Whittington, Ted Neward, Ian Griffiths, Serge Lidin, Craig Andera and Bill Conroy. Also, Chris Tavares will be spending most of July doing the actual implementation. If anyone else wants to dig in, feel free! I'm happy for the help and anyone that provides insight will get credit.
       
    • The goal of adding ref-counting to Rotor is to measure the performance effects of a deterministic finalization-like model that we gave up when moving from COM/C++/VB6 to .NET. I say "DF-like" because we're not getting DF, because the price of determinism is that sometimes an object is never finalized, e.g. cycles. We can do better.
       
    • We will not be replacing the existing GC's ref-tracking. It does a fabulous job managing memory and managing cycles and we won't touch that.
       
    • The ref-counting implementation's sole job will be to call an object's finalizer ASAP. Note that this is in no way "deterministic." Plain ref-counting is deterministic in that it calls an object's finalizer just as soon as there were no more outstanding object references. Cycles meant that this would never happen (deterministically). A hybrid ref-counting/ref-tracking system improves "never" to "eventually" in the case of a cycle and maintains the ref-counting's guarantee for ASAP in their absence.
       
    • Even objects that don't have finalizers will need ref-counts, as they maintain references to objects that have finalizers (and so on).
       
    • Value types will not need reference counts, but when they go out of scope, there will need to be a Release on any object references the value objects contain.
       
    • When the GC kicks in and finally breaks a cycle, it would be nice to release all objects held by the cyclic objects so that they could return to normal ref-counting determinism. However, since we've already blown determinism by being in a cycle, this seems unlikely to be very helpful. Also, by skipping this we can keep all of our changes in the JITter and out of the GC, which simplifies the initial implementation.
       
    • We'd plan on adding ref-counting at the runtime level in the JITter so that all languages gain the benefits w/o updating the compilers (or mandating anything special in any language). The real work is figuring out which IL instructions require AddRef/Release calls and getting those calls into the instruction stream. Because of this, we're not likely to be able to handle tail calls (at least, initially). Anyone with advise in this area would be welcomed with open arms.
       
    • We plan on working nicely with existing IDispose-based code. Since our ref-counting is all about calling the finalizer, if the ref-count gets to zero and there is no finalizer to call, no finalizer will be called. That means that Dispose implementations that call GC.SuppressFinalize will not cause any problems with the ref-counter. Of course, the goal is that the IDisposable.Dispose protocol is not necessary at all.
       
    • As a potential optimization, I have found a nice place to store a 7-bit ref-count in the existing space allocated to every object, so there will be no space overhead, only CPU overhead. However, this narrows the number of objects per  process with synch blocks and/or hash values from 134 million to 1 million. It also narrows the number of referencing objects from the traditional 4 billion to 127. Anecdotally, 127 seems like enough, but it will necessitate the need to abandon ref-counting on any object that reaches 127 extent references. Since most data structures where more than 127 references could happen are parent-child, e.g. every child in a tree with a reference to the root, and this indicates a cycle that can't be handled by the ref-counting anyway, turning these objects over to the ref-tracking portion of the algorithm seems reasonable. However, we won't know 'til we look how many object references an object is going to have, so we'll track maximum reference counts during our tests to see if this optimization makes sense at all.

    The Truth Is Not Enough

    Sun, May 26, 2002

    Watching the final episode of the X-Files, I realized why I don't like that show. Mulder spends all his time searching for the truth, but even when he finds the date of the planned alien invasion, he doesn't do anything with it! They've spent the last nine years discovering the truth and not doing anything to change it (or, if they do try, they fail miserably). Of course, that's not the only problem with the show (e.g. why would an alien race powerful enough to do generic engineering to produce the "miracle child" or to create "super soldiers" or to create the virus in the first place, needs to bother with setting up a shadow government), but it's the one that bothers me the most.

    Just knowing the truth is not enough. You need to act on it.

    I don't really know what that's got to do with the price of tea in China, but hey, you get what you pay for. : )

    The sellsbrothers.com Newsletter

    I've found that I can't just keep track of what I've added to my site for any period of time and if I can't keep track, I know that you guys can't keep track. So, with that in mind, I've decided to put together a little newsletter. The sellsbrothers.com newsletter is dedicated to bringing you news and features from the sellsbrothers.com site, including announcements of new materials, book reviews, software reviews, industry news and trends, new things I've learned and anything else I think you're going to be interested in related to software development in a Windows world. The newsletter is send only, so unlike the mailing list, you don't have to worry about filling your inbox will all kinds of mail you may or may not find amusing. I plan on publishing this newsletter periodically, but it will be very low traffic.

    Subscribe to the sellsbrothers.com newsletter.

    For the Love of the Story

    Thu, 5/9/02

    It's only happened a few times in my entire life, but I want it to happen more. It's that feeling you get when you're telling a story, trying to describe a scene or a technology or a something and, suddenly, without warning, it starts to tell you. It happened twice in college in a creative writing assignment: one of those times it actually gripped me from the moment I started writing my life story on a 3x5 card (I remember it started "I was an accident." : ). It happened once while writing ATL Internals: Chapter 7, Collections and Enumerations. And it just happened again while finishing up a writer's journal entry I started yesterday:

    Whack-thump-thump. Whack-thump-thump. The sound filled the first floor. Whack-thump-thump. Tom knew he wasn�t supposed to play ball in the house. Whack-thump-thump. His father, watching from the kitchen, had laid down that law several times when things had gotten out of hand. Whack-thump-thump. The ball continued hitting his hand, the floor and the door in the never-never land between the kitchen and the front entry. Whack-thump-thump. Tom, at 6, seemed to be using the mesmeric sounds to enter another place, somewhere regular, somewhere safe, somewhere comfortable. He had always been able to enter that place, whether he was playing with action figures, with clay or even with ordinary items like pencils or popsicle sticks, using them in the theater taking place in his head. Whack-thump-thump. Whack-thump-thump. His father was a much more literal thinker. He was creative, but creative in an engineering/problem-solving way and he envied his son�s ability to enter this world seemingly effortlessly, never getting bored when the ordinary world around him failed to offer what was safe and regular and comfortable. Whack-thump-thump. Whack-thump-thump.

    I started writing this to describe what my son Tom was doing yesterday morning just before school and it turned into a look into how much I loved and admired my 6-year-old son. He's so much different than me, but just like his mother and looking at him makes me realize just how much I love my wife. That's what writing is supposed to do. It's supposed to help you reach into your self and share what you've got with others. That's what this blog is all about and I appreciate you being here to listen.

    This is Not a Blog

    Fri, 3/13/02

    Web Logging (blogging) is the wave of the future. Blogging is re-making the internet. Blogging is journalism where everyone is the journalist. Blogging is all that and a bag of donuts.

    OK. I guess so. I like blogs. I read a bunch of blogs. But most bloggers feel like they have to update their site at least once/day and most do it far more than that. Because of this, their blog entries end up looking like this:

    [burb] Excuse me.

    [google this!] [comment on this! (0 comments so far)]

    It's not that I don't love to read a daily blow-by-blow of these peoples' lives... oh, wait, no, it is that. Maybe a little filtering would be handy?

    And while we're on to the filtering thing, maybe we could drop the meta-comments about blogging itself? How cool could blogging really be if every other entry is about the power of blogging itself or, even worse, a link to somebody who linked to your cool description of the power of blogging?!?

    Anyway, the spout is not a blog. I only update it when I think I've got something interesting to say (even if it's something that only I'm likely to think is interesting), I don't use any content management software (unless you count ASP.NET and FrontPage : ) and, except for this entry, I don't spend any time talking about the wonder of blogging itself.

    How Did You Get Your Start?

    Wed, 2/27/02

    Standing in the rain, with his head hung low, couldn't get a ticket, it was a sold out show, heard the roar of the crowd, he could picture the scene, put his ear to the wall and like a distant scream, he heard one guitar, just blew him away, saw stars in his eyes and the very next day, bought a beat-up six string in a second hand store, didn't know how to play it, but he knew for sure that one guitar felt good in his hands, didn't take long to understand, just one guitar, slunk way down low, was a one-way ticket, only one way to go, so he started rocking, ain't never gonna stop, gotta keep on rockin', someday gonna make it to the top and be a Jukebox Hero....

    Jukebox Hero, Foreigner

    It's my understanding that once a musician reaches a certain level of notoriety, they are often asked how they got their start, so that the fan can obtain the level of success that the musician has obtained. Over the years, I've received quite a few of these kinds of emails, all of which flatter and surprise me, since I don't feel like I've obtained the level of success that I'd like to. Still, I'm happy to offer, if not advice, than a list of what I did to obtain a level of recognition in our little circle.

    It all started in early 1994, when I went to work for DevelopMentor. Don's strategy, which remains in place to this day, was to give every instructor the opportunity for "stardom." He had just started to obtain his own notoriety in the industry with his flamboyant personality, teaching and answering every other question on the DCOM mailing list. From there, he used his political acumen to make friends with conference organizers and book publishers, working to add the same level of rigor to Windows development as he was accustomed to applying in the pursuit of his PhD.

    Since Don is a fellow that gains happiness in togetherness (or, put another way, "misery loves company"), he dragged the rest of us into his world of course authorship, 24x7 mailing lists, speaker anxiety, article deadlines and demanding book editors. To find my place in this world, I did the following, leveraging the success I had in the early work to make the later work happen:

    • Answered every other question on the DCOM and ATL mailing lists and continue to be very active on the .NET mailing list.
    • Wrote and gave numerous courses and conference talks.
    • Wrote a number of books and articles.
    • Put up a web site dedicated, initially, to the various bits and pieces of code I'd built and then expanded it as I had more to say (which turned out to be quite a lot, apparently : ).
    • Took as much consulting as I could to gain real-world experience, which I put into my other work.
    • Asked fans and happy clients to post their comments on Amazon or allow me to post to my own web site.
    • Crazy things just for fun, e.g. pose naked or misinterpret an email on purpose in order to post a humorous response.
    • Made friends with the owners and producers of the technology in which I was interested.
    • Threw a couple of conferences.
    • Started (and stopped) a department to build software developer tools.
    • Launched my own (budding) software development tools.
    • Launched a couple of source available projects with folks from the community.
    • Launched my own mailing list.

    It seems like a lot, but practically everything I've done since 1994 has been published with my name on it, making me as much an agent for myself as an actual "musician" (I believe the phrase is "shameless self-promotion" : ). Based on this experience, here are the guiding principles that I try to follow:

    • Do the right thing. My father always used to say that anything worth doing was worth doing right and that the right thing was easy to spot -- its was the hardest.
    • You can't win if you don't bet.
    • Be very thorough so that I can be sure of myself, leading to...
    • Take a stand. Have an opinion. Defend my opinion until I have been convinced of my mistake, then admit my mistake and take up the opposite stand with equal vigor.
    • Try a lot of things and don't be afraid to make mistakes.
    • Be quick to give credit and admit mistakes, both in public and in private.
    • Recognize opportunity and follow up.
    • Get down to the real "why" of something, whether it's computer technology or another kind of technical discipline.
    • Recognize the people, on the other hand, don't always have a "why," and learn to deal with it (I still work on that!).
    • Always strive for quality over the quick and dirty.
    • Concentrate on the things that I really want to do. I like to say "Only do those things that you can't *not* do," but in a down economy, I've learned to temper that with fiscal reality.
    • Finish what I start.
    • Make sure people are happy with my work and don't stop 'til they are.
    • Have balance in my life. I have a wife and children that I love and spend as much time with as possible.
    • Horse trade. I am always willing to offer what I have, e.g. experience, time, contacts, etc, for what I want, e.g. work, money, content, etc.
    • Help other people find their own places. I'm constantly concerned with my friends and their happiness and will do whatever I can to help them get to do whatever it is that they "can't not do." This is a lesson I learned from Don. He helped me to become all that I could be and, in turn, I do my best to help others.

    Actually, most of this I learned from Don, either directly or indirectly. I guess my only real piece of advise is to try to find someone you admire and to do what they do. Don was my main mentor, but I've had many over the years and they're invaluable, even if all I had was a beat-up six string...

    Please Say "Why"

    Wed, 2/27/02

    As .NET demands new books and articles and the economy has given a lot of smart folk free time, the world is becoming inundated in .NET books, articles, talks and courses, many of which I am tapped to review. Some are wonderful. Some are awful. Most, however are *almost* good, the path to goodness well within the author's reach but for the answer to one question: "why?"

    Most of my feedback is riddled with questions that start with why: "Why was it built this way?" "Why are there three choices and how do I choose?" "Why should I care?" Please, when you write, remember this question and answer it thoroughly and well. The why is *so* much more important than the how. The online documentation for .NET is fabulous for describing the how, once you understand the motivation for this class, that method or the other namespace.

    Prose that provides the how is transient, but prose that provides the why becomes classic because the why itself is surprisingly applicable between technologies. At the very least, if you answer the why, it will save me work if I'm to review your prose.

    HTTP is Dead?

    Wed, 2/27/02

    Your friend and mine, Don Box, caused quite a stir yesterday with his keynote at European DevWeek in London. Peter Drayton has also written up a summary (which is much more technically meaty), as well as a commentary. There has been some quite spiriting follow up on this talk all over the Internet: the .NET mailing list, the Off Topic mailing list, the REST mailing list and XML Deviant on XML.COM. Also, while I absolutely agree with Don that the way we use HTTP today leads to trouble, I thought that Ian Griffiths, a fellow DevelopMentor instructor, had a wonderful point of view that he allowed me to share:

    Guest opinion by Ian Griffiths

    Basically Don seemed to be saying that there are two problems with HTTP (and saying HTTP is dead is just an effective way of getting people to listen; I was half tempted to start my Windows Forms speech at the UK MSDN DevCon with "The Web Application is Dead").

    One of these is that HTTP is unidirectional. Surely .NET remoting shows that this isn't strictly true: individual connections are directional but it's entirely possible to do callbacks by having connections go in both directions. (Well duh.) The real problem is that the firewall architectures of the internet are designed to make sure the connections only go in one direction; it's not a problem with the protocol per se, it's a problem with the infrastructure. In order to fix this problem you need to change the infrastructure regardless of what you do to the protocol. And if you fix the infrastructure you don't actually need to fix the protocol, since we already know that it's fine on networks that don't deliberately break bidirectional communication.

    Arguably one of the main obstacles here is the use of NAT - NAT makes it hard for a client behind a firewall to publish an endpoint. But NAT is fundamentally important because we'd have run out of IP addresses already if it weren't in such widespread use. So the only way to get rid of NAT is for everyone to upgrade to IPv6. This will presumably happen fairly soon since we will run out of IP addresses in any case in about 3 or 4 years. (Windows XP ships with IPv6 support by the way. Type "ipv6 install" at a command prompt if you haven't already. So Microsoft are quietly making IPv6 ubiquitous on the desktop.)

    So presuming ipv6 takes off, that's a fundamental technical obstacle to the one-way nature of HTTP removed. But another one remains: just because IPv6 pushes the address exhaustion date out of our lifetimes (we hope), doesn't mean that firewall admins will let connections work both ways through the firewall. The bidirectional problem can only be solved with the blessing of firewall admins. And once you have that you don't actually need IPv6, strictly speaking - given a suitable protocol between the client machines and the firewall there's no reason that NAT can't be done in both directions. (Indeed my sub-$100 firewall appliance can do this on a statically configured basis. It is possible (if a little inconvenient) for machines behind the firewall to publish endpoints successfully.)

    UPnP apparently has a solution for this. (A better one than static configuration.) It supports P2P network applications that require clients behind the firewall to be able to accept incoming connections. It defines precisely what you need: a protocol that lets a client machine negotiate with the firewall to open up a port for incoming connections. So it turns out that a technical solution to the problem already exists. (Without even having to invoke IPv6. Although we still need that, due to a shortage of address bits in IPv4.)

    So the first problem already has a technical solution. Presume for a moment (and it's a big presumption) that these solutions can be deployed, and firewall admin policies set up so that they are broadly useable.

    At this point, the second complaint Don makes - the fact that long-running requests don't sit well with HTTP - becomes much less of an issue. We just need to use separate HTTP requests for the request and the response. We connect to the server, send a request, along with some response endpoint info (a URL). When the server is done it connects to us, sends us a response. And we're done. I'm guessing it would probably be possible to write a .NET remoting channel that works like this. The only obstacle is the ability for clients to advertise endpoints.

    So if a client can advertise an endpoint somehow (i.e. it can (a) convince the firewall to let a connection request come in, and (b) work out what the endpoint should be - it needs to be aware of any NAT translation going on) then HTTP can actually solve both the problems raised here. And as far as I can tell, *any* solution to the problems raised is going to have to allow the client to receive incoming requests. In which case why invent a new protocol? Once you've solved the fundamental problems in the network that stop you from doing this, HTTP is good enough.

    The only issues are: (1) getting everyone to agree on how clients will expose endpoints (UPnP has had nothing but bad press so far, since the only thing most people know about it is that the first security hole discovered in Windows XP was connected to it somehow; so it might have to be something else...), and (2) convincing firewall admins to allow this functionality to be used.

    Of course just because a technical solution exists doesn't mean it's a great solution. Given that this is a fair distance from HTTP as originally envisaged, it would doubtless be possible to design a protocol better suited to the job. But would the benefits be worth it? Everyone already has an HTTP stack and an XML parser - will they flock to implement a new purpose-built solution?

    The problems raised in the ZDnet article can essentially be summed up thus: clients can't expose endpoints. To me, this doesn't look like a problem with HTTP, it's a problem with the infrastructure. Changing the protocol is certainly not sufficient to fix the infrastructure problems; it's not clear to me that it is even necessary.

    So really this is a social problem, not a technical one. ;-)

    If you're interested in this topic or what other interesting things Don will say next, he's giving the keynote address at the Web Services DevCon on March 21-22 in Beaverton, OR (10 minutes west of Portland).

    A Visit with the Visual C++ Team

    Tue, 1/22/02

    I spent a fun two days up at Microsoft last week at the Visual Studio .NET C++ Authors Summit, wherein the Microsoft team shows us how cool VS.NET is for C++ and browbeat us to write a book on the topic. Since I'm already planning to write ATL Internals, 2/e with Kirk Fertitta, I couldn't talk them out of the XBox I so richly deserve. On top of that, they tortured me by taking me to the Microsoft store where they have XBox games for only $10! Those bastards...

    If you're a C++ programmer, VS.NET/VC7 brings a lot to the table. And according to Nick Hodapp, a PM on the VC team at Microsoft, many, many of you are C++ programmers. Microsoft quoted some 3rd party studies that say that there are about 3M C++ programmers out there (compared to 5M VB programmers and a whole lot less Java programmers). From a 3rd party survey of VC++ customers, Microsoft found that 90% (!) of them will be doing the same or more VC++ work in the future (about 22 hours/week). They also found that about 75% of VC++ users are MFC programmers (which isn't growing) and 35% of them are ATL programmers (and is growing). Given the number of ATL7 books shipping right now or in progress (ours and a few more), and the increase in the audience, that made Kirk, my Addison-Wesley editor and me very, very happy.

    Here are some other interesting tidbits from that survey for you:

    • 68% of VC++ developers build client-server apps
    • 61% build desktop apps
    • 51% build peer-to-peer apps (This number slays me. What are these guys building?!?)
    • 36% build embedded/CE apps
    • 35% build NT services

    While we were there, various members of the VC++ team attempted to rock our world in terms of the new and improved features VC7. Sometimes they succeeded. For example, Pranish Kumar told us how the ATL Server version of the Nile benchmark web application was 10% faster than the hand-turned ISAPI version in 1/4th the development time, which is why the Microsoft site uses it for some of their "through-put challenged" areas. Also, Terry Leeper showed us how make mini-dumps for VC++ projects that you can send to the developer's who persist in saying "but it works on my machine..." He also showed us how you can pause threads during debugging, load symbols on demand, set breakpoints in DLLs that aren't loaded at start-up (without that annoying dialog box) and just how much the new optimization features can speed up your code (they did an amazing demo with a recompiled Microsoft codedec that nearly doubled the frame rate with no code changes).

    For those of you into ANSI compliance, Microsoft showed off an early internal build of their compiler that raises VC's over all compliance rating to among the highest in the industry. They are able to compile all of the popular 3rd party template libraries, e.g. Loki, Boost, Blitz++, POOMA and a complete STL.

    Now the Fun Begins

    Wed, 1/16/02

    Last night at 4:46pm, Sara Williams announced the availability of Microsoft's 4+ years of labor: the Microsoft .NET Framework, v1.0. And then, at 5:59pm, the great land rush to download the matching VS.NET bits began. Here are some links you may find interesting as you move to the RTM of .NET and VS.NET:

    Here are some fun facts for you:

    • The compressed VS.NET Enterprise Architect download is 1.8GB and it took my puny cable model 4+ hours to download.
    • It took my laptop (574MHz, 512MB RAM) 30+ minutes to unzip.
    • The resulting pre-installed folder was 2.45GB.
    • The .NET runtime build number is 3705.
    • The VS.NET build number is 9466.
    • The codename for .NET was "Lightning" (hence the ildasm icon).
    • The codename for C# was "Cool" (hence the "C# is Cool" t-shirt).
    • Mike Woodring's most excellent asmstats tool reveals the following:

      Done processing c:\windows\microsoft.net\Framework\v1.0.3705.
      Processed 69 assemblies comprising 70 modules.

      Types: 8,866 (of any kind)
      Classes: 5,602 (2,183 public)
      Attributes: 297 (257 public)
      Delegates: 334 (213 public)
      Interfaces: 983 (659 public)
      Enums: 1,085 (710 public)
      Value types: 565 (121 public)

      Members: 414,990 (of any kind, instance and static)
      Methods: 281,630 instance, 12,797 static
      Events: 13,160 instance, 24 static
      Properties: 44,689 instance, 1,233 static
      Fields: 28,478 instance, 32,979 static

    Congrats to the Microsoft .NET team for a job well done!

    VS.NET Fun Facts

    1/6/02

    After about a month of banging my head on it, Visual Studio.NET has become my favorite IDE of all time. To save you the bruising, I thought I'd post some productivity tricks and traps I've learned [1] that make VS.NET useful. If you've got your own, send them to me and I'll post the good ones.

    DISCLAIMER: I always leave the standard VS.NET key bindings, i.e. I don't set it to VC6 style. In general, I just learn the default keystrokes for things instead of changing them. Saves me time when repaving my machines or sitting down at strange machines. If you've changed key bindings in your VS.NET, these keystrokes aren't likely to work, but the tricks will still be useful if you can figure out what the key bindings are.

    Download

    If you don't already have VS.NET, run, don't walk, to MSDN to download a 60-day evaluation of VS.NET Professional.

    Tricks

    • The most important thing I've done to make VS.NET useful for me is to unpin all of the windows. This gives me tons of room for the source or design view. This, combined with the keystrokes to pull out the windows (below) as I need them, is probably my favorite feature of VS.NET.
       
    • The 2nd most important thing to know is that VS.NET can be invoked from Start->Run using its name "devenv" (no quotes). Therefore, to start VS.NET, type Ctrl-Esc, R, devenv, Enter. Much better than digging into the deep Programs menu.
       
    • Make sure to move the "Visual Studio .NET Command Prompt" that's buried deep inside of Start->Programs->Microsoft Visual Studio .NET->Visual Studio .NET Tools to somewhere more handy, e.g. the Quick Launch toolbar, so that you can get to it easily. You'll be using the command shell often in your .NET development.
       
    • Let the IDE implement the stubs of an interface function in a class (not a struct):
      1. Type the name of the interface after the name of the class, e.g. "class Foo : IDisposable".
      2. In the Class View (Ctrl-Shift-C), navigate to the class, e.g. Foo, and choose the interface you'd like stubs for under Bases and Interfaces for that class.
      3. In the context menu (Shift-F10), choose Add->Implement Interface.
      4. Bask in the glory of Don Box (who showed me this trick).
         
    • Let the IDE implement the stub of an virtual function override:
      1. In the Class View (Ctrl-Shift-C), navigate to the class, e.g. Foo, and choose the method on the base class you'd like to override under Bases and Interfaces for that class.
      2. In the context menu (Shift-F10), choose Add->Override.
      3. Bask in the glory of me, who found this all by myself. I found this digging through the .VSZ files on my system. It looks like you can add your own context items to the menus, which sounds like fun...
         
    • If you'd like some samples of VS.NET Add-Ins, MS provides some. MSDN Magazine provides an add-in article that you may find useful.
       
    • Likewise, Leo A. Notenboom has written a thorough article about how to write an add-in to VS.NET.
       
    • Also, in A Designable PropertyTree for VS.NET: Russell Morris has built an implementation of the PropertyTree control that you see in VS.NET's Project Properties dialog. What makes this really cool is that Russell's control is a great example of what to do to integrate with the VS.NET Forms Designer.
       
    • If you'd like to add to the Solution, Project, Project Item or Context Menu wizards for VC++, VC# or VB.NET, you can. Here's an example of a project item wizard that produces a custom aspx file and a custom code behind file to go with it.
       
    • While ildasm.exe is very thorough, if you'd like to have a prettier view of the types in an assembly, you can load it into the VS.NET Object Browser. Using the file open dialog, click the drop-down and choose Open With and select the Object Browser. Once it's loaded, you can unload it by choosing the Remove item from the context menu of the assembly in the Object Browser.
       
    • This isn't a tip so much as an observation. If you use an #if with a compilation symbol, e.g. DEBUG or TRACE, notice that as you move from configuration to configuration that the editor will gray out the code path that won't be taken. Is that cool, or what?!?
       
    • Read the online documentation. It's *so* much more useful than the online documentation of old.
       
    • Brock Allen showed me the 3rd tab (Projects) in the Add References dialog for adding references from one project to the target of another. This works *so* much better than hard-coding .NET references to a specific output folder.
       
    • Ed Stegman pointed out that the Toolbox can be used to store snippets of code. Simply select some and drag-n-drop it on the Toolbox. To paste, drag-n-drop from the Toolbox to your editor. Of course, this is great for duplicating bugs as well. : )
       
    • Ed really likes regions, marked using #region/#endregion compiler directives, too. Now that's he's clued me into the keystrokes (below) for expanding and collapsing them, I really like them, too. : )
       
    • Ed also reminded me of the Task List and how anything marked with TODO, HACK or UNDONE will be included in your list of tasks. Andrew Stopford reminded me that you can set up your own keywords via Tools -> Options -> Environment.
       
    • If, on the other hand, you hate the Task List, Kevin Perry suggested the followings steps to turn if off after a build:
      1. Go to Tools -> Options -> Environment -> Project and Solutions.
      2. Uncheck the "Show task list window if build finishes with errors" option.
      3. Make sure the "Show output window when build starts" option is checked.
      4. Now go and close the task list window and it's gone for good!
         
    • Several folks have sent along macros that are life savers to them. If you'd like to do that, I'm happy to post them here along with your name and a brief description. Please send attached files instead of inline text, however. Thanks!
    • Drew Marsh pointed out that Ctrl-S works in any of the output windows, e.g. build, debug, etc, to save the contents to a file.
       

    • It's cool to have MS folk reading this list. Kevin Perry sent me to procedure to bypass the "Attach to Process" dialog that asks what kind of debugger you'd like to pick, i.e. CLR, T-SQL, Native and/or Script, when you click on the Attach... button in the Debug Processes dialog. Ctrl-clicking on Attach... will give you the Native debugger without asking.
       

    • My good friend Tim Ewald reminded me that one of the coolest features of VS.NET is that the solution explorer is really just a view of your actual project folders in the shell. This is especially useful if you choose Show All Files, so that you can add files to your project that are already in your project directory simply by using the context menu. If you'd like to add a file that isn't in your project, you can do so by opening the file and choosing "Move <file> into Project" from the context menu. This is a poorly named item, however, as it actually links to the existing file outside the project instead of moving it in the file system (although the linking is the correct behavior).
       

    • To speed the IDE start-up time, you want to avoid the browser being loaded. To do that, from the Start Page, choose My Profile and set At Startup to Show empty environment. Also, close the Dynamic Help window and the Start Page. Now IE will only be loaded on demand.
       

    • If you like the tabs showing the various files you have open, but miss the ability to show multiple files at the same time, right-click on one of the tabs and choose New Horizontal/Vertical Tab Group. Both tab groups will show simultaneously and you can move tabs (and therefore the window that the tab represents) between tab groups by right-clicking on the tab.
       

    • Maria Abreu points out that VS.NET, by default, neglects to colorize strings (an omission, IMO). You can colorize them via Tools->Options->Fonts and Colors and it really helps. Thanks, Maria.
       

    • Graeme Foster posted this tip on the DOTNET mailing list for getting VS.NET to copy the application .config file during the build: simply name the file app.config and put it in the main project directory. At build time, VS.NET will copy the file into the output directory with the build output.
       

    • Dominick Baier reminded me that by typing "///" (no quotes) above the declaration of a method or property, the C# editor will give you the template for the C# XML documentation tags with all parameters and return value. The IDE will compose these comments into (fairly ugly) HTML-based documentation for your classes using the Tools->Build Comment Web Pages menu item. A much nicer set of documentation from these comments can be generated by NDoc.
       

    • Kunal Cheda pointed out that if you've got multiple things you'd like to start when running or debugging a solution, you can do so at Solution Explorer->Solution Properties->Startup Project->Multiple Startup Projects. *Very* handy for client-server testing.
       

    • Nick Hodapp passed along this tip on how to exclude included files that don't change from VC++ dependency checking:
       

      1. Add header file directory names (using full, absolute paths) one per line, to SYSINCL.dat.

      2. Exit the development environment.

      3. Restart the development environment.

      4. Click Rebuild for changes to take effect, noticing a reduction in build times.
         

    • Shawn Van Ness thinks that the clipboard ring "is so cool, it should be back-propped into all of Windows": Using Ctrl+Shift+V as an alternative to the usual Ctrl+V paste command, will "cycle" through the last dozen or so bits of text you've copied onto the clipboard. This simple user scenario demonstrates:
       

      1. Copy "#if DEBUG" onto the clipboard.

      2. A few lines below, copy "#else" onto the clipboard.

      3. A few lines further below, copy "#endif" onto the clipboard.

      4. Scroll down many hundreds of lines... or open a different file, etc.

      5. Ctrl+Shift+V to paste "#endif".

      6. Ctrl+Shift+V, Ctrl+Shift+V to paste "#else".

      7. Ctrl+Shift+V, Ctrl+Shift+V, Ctrl+Shift+V to paste "#if DEBUG".
         

    • Scott Hanselman pointed out that you can set the font size to VS.NET from the command line using the /fs argument, e.g. "devenv.exe /fs 14". This is great for presenters!
       

    • For the complete list of key bindings, MS provides a Keybindings Table Add-In. Here it is already compiled. Just drop it anywhere, register it as a COM server and the next time you start VS, you'll have a KeyMap command in the Help menu.
       

    • Russell Sinclair has provided his favorite key bindings in an Excel spreadsheet that prints and folds nicely for keeping it handy.
       

    • Here are my favorite key bindings:
       
      Keys Binding
      F8/Shift-F8 Navigate compilation errors
      Ctrl-D Move to mini-buffer
      Ctrl-Shift-G in mini-buffer or
      Ctrl-O in mini-buffer
      Open file name in mini-buffer (Ctrl-O seems to open stuff Ctrl-Shift-G does not)
      "> command" in mini-buffer Execute command
      Ctrl+/ Move to mini-buffer, typing the leading > for you
      Ctrl-Alt-A Open the command window
      Ctrl-PageUp in HTML Design View Open source view
      Ctrl-PageDown in HTML Source View Open design view
      F7 in Form Design View Open source view
      Shift-F7 in Form Source View Open design view
      Ctrl-Alt-L Solution Explorer
      F4 or Alt-Enter Properties of selected item
      Ctrl-Shift-B Build
      F5 Debug
      Ctrl-F5 Run, but not debug
      Ctrl-Alt-J Object Browser
      Ctrl-Shift-C Class View
      Ctrl-Space when typing a symbol Complete the symbol you're currently typing or give you a choice of possibilities
      Ctrl-Space when entering arguments Show the function prototype
      "-" (no quotes) as the name of a menu item Menu item becomes a separator
      Ctrl-K Ctrl-F Reformat selection
      } Reformat scope being closed
      Ctrl-K Ctrl-C Comment out selected lines
      Ctrl-K Ctrl-U Uncomment selected lines
      Ctrl-} Match braces, brackets or compiler directives
      Shift-Ctrl-} Select match between braces, brackets or compiler directives
      Ctrl-L or Shift-Del or
      Ctrl-X w/ no selection
      Delete entire line
      Ctrl-Del Delete next "word"
      Alt-F6 Next visible pane (not for use with all windows unpinned)
      Ctrl-Shift-F12 Jumps to next *whatever*, depending on what's active, e.g. next find result, next task, next error, etc.
      Ctrl-"-"/Ctrl-Shift-"-" (no quotes) Jumps to last/next place you worked
      Ctrl-C in the Class View Copies fully qualified name to the Clipboard
      Ctrl-M Ctrl-M Collapse or expand a region or outlined block (as marked by the [+] and [-] on the left hand side of the editor).
      Ctrl-M Ctrl-O Collapse everything in the current file
      Ctrl-M Ctrl-L Expand everything in the current file
      F12 Jump to the current symbol's declaration
      Ctrl-G, line #, Enter or
      Ctrl-D, line #, Ctrl-G
      Jump to line
      Ctrl-I/Ctrl-Shift-I + string Incremental search for string
      Ctrl-R+Ctrl-R Turn on/off word wrap
      Ctrl+Up/Down Arrow Scroll window up/down without moving the cursor away from the current line
      Shift+Alt+Arrows
      (Alt+Mouse works, too)
      Column selection (include of line selection)

    Traps

    • VS.NET's Copy Project uses FrontPage Extensions to publish a web site from a local testing machine to the deployment machine. This is virtually important if you don't want to hack on your live web sites. However, Copy Project sends everything every time instead of sending the deltas, so it's pretty worthless as far as I can tell. Instead, Brad Wilson clued me into the FrontPage Publish Web command, which only publishes deltas.
       
    • The command window (or > in the mini-buffer) seems really cool, but I don't know any good commands to type. Do you?
       
      • Joe Bauer points out that you can, of course, use the command window to print fields or call methods using the ?, e.g. "> ? objMyClass.GetCount()".
      • Richard Birkby pointed out the "shell" command, which seems a bit unwieldy for me, but you may like it. ">shell /?" in the mini-buffer will show usage (now that's cool!).
      • Drew Marsh points out that the command window (or the mini-buffer with a > prefix) allows you to execute any command provided by the shell, add-ins, or macros. Anything you don't bind to a key combination or toolbar button, you can go into the command window to execute. Also, it supports auto-completion for those of us with poor memories.
      • Richard Broida pointed out the use of the "?" command to print variables at debug time.
      • John Lam showed me where the docs are for the pre-defined command aliases. He also points out that you can create your own aliases, but you need cool commands first before you can do that. : )
      • Ramakrishna Vavilala recommends a cool alias ">alias ! shell /command cmd /c" which reduces the syntax of the shell command considerably and sends the command output to the Command window.

      • Don Box pointed me at two commands that forces me to learn the keyboard shortcut to put focus in the command window (Ctrl-Alt-A):
         

        • ">open <partial path>" will give Intellisense on the file system, e.g. ">open c:\".
           

        • ">File.NewFile <file name>" will open a new file with the appropriate name and syntax highlighting, e.g. ">open foo.cs". This is even handier when you alias "new" to File.NewFile, e.g. ">alias new File.NewFile", because you can just do this ">new foo.cs".
           

    • As far as I can tell, there is no way in a C# project to run custom pre or post-build commands, either on a project or a file level. If the VC++ wizards still had a Utility project, that could be used, but the closest I've seen in VS.NET is a Makefile project. Anyone have ideas on this one?
       
      • Several folks have recommended a VS.NET Add-In Sample that is supposed to provide this capability.
      • Kevin Perry showed me where the UI scrambler put the Utility project in this version of the IDE:
        1. Run the makefile appwizard to create a makefile project.
        2. Bring up the project properties for the project and look at the general page
        3. Select �Utility� in the �Configuration Type� property drop down.
        4. Click Apply.
          POOF! Instant Utility project.
          BTW: C++ Static Library projects can also double as utility projects in a pinch.
           
    • As cute as the Add Reference menu item is on a project's context menu, your going to have to avoid Add Reference for COM servers and build the references by hand if you sign your assemblies (which you should always do). Apparently a signed assembly is not allowed to reference an assembly that's not signed and the Add Reference menu item doesn't sign the generated assembly. All Add Reference does is the moral equivalent of the tlbimp command line tool anyway, so get used to calling it yourself using the /keyfile command line argument. If you import COM Controls, e.g. the WebBrowser control, you'll need to use aximp instead of tlbimp, but the /keyfile argument is the same.

      However, Jerry Dennany points out that you can have VS.NET itself sign your interop assemblies by going to the Project Properties, and under Common Properties / General there will be a section for "wrapper Assembly for ActiveX / COM Objects." You may place your path to the Key File here, and everything still works from the IDE.
       
    • There are no wizards for standard SDI, MDI or Explorer-style applications in WinForms as there were in VC++ for MFC applications. However, the wizard stuff is there, although it's obscure, so maybe I'll build one. I've certainly done my share of that kind of work...
       
    • Likewise, there is no built in support for MFC-style document handling, separation of data and view, command line processing or command UI handling. I've done my share of that kind of work, too, and I *will* be building that stuff. Anyone want to volunteer to help?
       
    • I don't seem to be able to get a custom control on the toolbox unless it's part of a separate assembly. What if I have a custom control in my application? Can I make it show up on the toolbox somehow?
       
      • Bob Beauchemin pointed out that I can customize the toolbox and point it at a built version of my EXE, which sounds kind of awkward, but works.
         
    • I can't tell. Is everything being recompiled every time I build, regardless of whether the source has changed or not?
       
      • Drew Marsh pointed out that the Incremental Build option in a C# project will decide whether you rebuild only if it is changed or not.
         
    • If a file is "thought of" internally by the IDE as one text, e.g. Text, and you try to save it as another type, e.g. XML, if you're not very careful the save dialog will append the extension of the type it thinks it is, e.g. .txt. To enforce the extension you want, put double quotes around the file name, e.g. "foo.xml".
       
    • Neither BeginInvoke nor EndInvoke is shown when calling methods on a delegate in C#, even though they do in VB.NET. This just seems wrong...
       
    • Docs on the built-in VsWizardEngine that VS.NET provides would be nice.
       
      • Jon Flanders says that they're documented as part of Enterprise Templates.
         
    • By default, adding a new project to an existing solution wants to put the new project in a peer directory instead of in a sub-directory. This seems strange if you're trying to keep these things together (which, presumably, you are if you're grouping multiple projects into a single solution). Certainly, I've seen users dig through several peer directories looking for the solution file. I put sub-projects into sub-directories by hand, but it would be nice if the IDE did this automatically.
       
    • Cleaning a project of it's output files doesn't actually work for C# or VB.NET projects (although the UI shows it as an option, as does the command line). Tomas Restrepo has provided an add-in that provides the missing Clean functionality, along with a rant on what problems he had building the add-in.
       
    • In spite of CodeWright and every other 3rd party editor supporting it for years, VS still doesn't support keyword expansion, e.g. expanding "if( " into "if( | )\n{\n}", so I use Dexter, from NilgiriHouse. I don't have to change my typing habits at all, but I get tons o' text for free.
       
    • The macro recorder is pretty stunted. For example, if I want a macro to switch between some editor settings, e.g. my normal code formatting style and my prose code formatting style, and I record a macro to watch me change the settings, all the recorded macro does is record that the dialog was shown, not what settings I changed. What a let down...

    [1] I've learned a ton of these tricks and traps from my fellow DevelopMentor instructors, my students and the .NET mailing list, all of which I can heartily recommend.

    Too Many Secrets

    Tue, 12/18/01

    During my three years as director of a software project, I learned a lot about people. In fact, I have a little text file entitled "My life as a dog" that may find a home on this site one day. However, because of a thread on the Windows Technical Off Topic list, one of the things I learned came roaring back like a bad acid trip.

    The #1 problem with any organization is always communication. You can do postmortems on projects all day long and only #2 and above will be a surprise. The problem is that to build anything of any size, you need a team. As soon as you have to communicate what's in your head to some number of other people, it's going to happen imperfectly. The best way that we've been able to come up with to deal with this issue is hierarchical structures to practice selective information hiding, i.e. exactly the way we build software.

    However, unlike software, humans have feelings and as soon as they perceive that somebody is hiding something from them, they resent it. Again and again, when I see information withheld to hide "bad" news, those being hidden from know something is up and they get upset. And when they're upset, they send emails and IMs and phone calls around the company looking for every scrap of information they can find, all the while ignoring the work that suddenly seems a waste of time in the face of impending doom. The surprising thing is that when folks are given the truth openly and honestly, no matter how bad it is, they almost always dig in and deal with it. Just knowing that they're trusted with the secrets of the company seems to boost morale.

    I'm not saying that everyone needs to post their daily activities for everyone to see -- that's too much information. But I am saying that everyone from the CEO on down should be open about the issues they face, including being open to scrutiny and suggestions. I find that after doing that long enough, folks working for me tend to trust me to make the right decisions, leaving them to focus on their own work.

    The key is that, unlike software systems where components have information hidden from them by their clients, humans can only be effective if they know that the information is available when they want it. Information hiding still needs to happen, but it's humans that need to choose to hide information from themselves. It whole thing falls apart if the managers do the hiding.

    Effective C# Available Today

    Sat, 12/1/01

    Effective C# is available now from Addison-Wesley. Of course, it's called Effective Java, but *wow* the overlap is amazing. Some of his items I don't agree with, e.g. return zero-length arrays instead of null (although I see his side) and others have been "fixed" due to advances in C#, e.g. override clone judiciously, but so much of it makes sense in C# (and .NET in general) that it's scary. I feel like asking AW for the text so that I can port it to C# over the weekend. : )

    Thank You, Don Box

    Fri, 11/16/01

    Last night, in the middle of .NET Band on the Runtime set, Don announced his retirement from DevelopMentor and training. He's sorry to be leaving us, of course, as we are to lose him, but he's excited about doing new things. Running a company gets more consuming as a company gets more successful and Don certainly brought DevelopMentor a great deal of success. And not only did he run his part of the company, but he also brought a amount of rigor and insight to an amazing range of technology topics, including C++, COM, DCOM, RPC, XML, Java and .NET, heretofore unprecedented in the training industry. He turned the phrase "them that can't; teach" on its ear. But these are things that are well-known of Don.

    What is perhaps not so well known is the care and dedication that he had for his friends and colleagues. He worked hard to turn his personal success into opportunities for the other technical staff members at DevelopMentor. And he succeeded. He paved the way for people like Ted Pattison, Keith Brown, Tim Ewald, Aaron Skonnard, Martin Gudgin and a host of others who's made a name for themselves in this industry. Of course, I'm also on this list. If you look at the things that I've got listed on this site, i.e. books, articles, courses, conference talks, etc, a staggering amount of it was enabled either directly or indirectly by Don Box. He's an amazing man and it's been an honor and a privilege to work with him these last six years. They're been the richest of my career and of my life. And for that, I'd like to thank him.

    Before we get too blubbery, Don has assured the world that he will continue to pursue technology and to communicate it to an eager audience. I, for one, look forward to what he decides to do next. Whatever it is, I'm sure it will be uniquely Don.

    If you knew .NET like I know .NET...

    Sun, 11/11/01

    Many years ago when Java was new, I dove in. My first program I wrote like a C++ programmer and I didn't get it. Then I rewrote the program as a Java program and it was much nicer, but I still didn't get it. Then I discovered the lack of deterministic finalization and that's all she wrote; my C++ thinking turned me away (the fact that Java was ashamed of my favorite platform and, in fact, all platforms didn't help).

    Now I've spent the last year doing .NET programming, mostly focused on Managed C++ and I didn't get it. I've participated in DevelopMentor's ASP.NET and Guerrilla .NET and loved both of them, but still didn't get it. I rewrote (with my good friend Jon's help) my entire web site in ASP.NET and didn't get it. And I spent most of last week preparing for my teach of the latest version of DevelopMentor's Essential .NET and I *still* didn't get it. Until today. Today I finally got it. The major power of Java wasn't that it was platform independent, as Sun so often touts. The power of Java (and therefore the power of .NET) is that it provides a major productivity boost for the programmer. I realized this today for the first time.

    It started yesterday. Yesterday I ported a tiny little application (a time client) from MFC and C++ to .NET and C#. The first time I ported it, I ported it like it was still C++ and the result was ugly (I was trying to do the standard library trick of representing time as a the number of seconds since some marker time and then translating it into a formatted string at the last moment). In fact, I couldn't even do the nice formatting of the current time since .NET didn't support that means of conversion. But then I remembered that, unlike C++, .NET has proper date, time and span classes. Once I rewrote it in .NET style, it was a thing of beauty. With knowledge of only the name of the sockets namespace (System.Net), I was able to learn .NET and build a time client in under an hour. To paraphrase the closing sentence of one of my first articles, it just makes you want to grab the back the of computer monitor and feel the power of .NET.

    Encouraged by my success and armed with the courage of my convictions (and a couple of web sites given me by Jason and Peter), I sat down to write a MSN Instant Messenger application. Those of you unlucky enough to have me as an IM contact saw me log in and log out about a hundred times yesterday (sorry : ). This was because every step of the way, I'd run my client and every step of the way, I'd make more progress. 90% of my code was reading and writing from the sockets and parsing strings. For the former, I used the StreamReader and StreamWriter and for the latter, I used the Regex class. Both did a ton of heavy lifting so I didn't have to. It was amazing.

    But yesterday, I still didn't get it. I was so focused on getting my IM client working (about a half day's work) that I completely missed the magnitude of what I was doing. I was implementing an async notification-based socket protocol after reading an example doc, skimming a spec and digging in. And the code I ended up with wasn't spaghetti. It wasn't production ready yet (my error handling, while present, was rudimentary) and I didn't implement the entire spec, but I had refactored along the way and now I have the beginnings of a nice little namespace for doing IM work. And all of this happened the same day that I first discovered the existence of the System.Net namespace. It's only after reflection (and a good night's sleep) that I finally get it. The power of .NET is the programmer productivity.

    This productivity comes from a combination of ease of use and flexibility that's going to attract almost everyone. It will attract the VB programmers because of the continued ease of use and the new functionality of the .NET Foundation Classes. It's also going to attract the C++ and the Java programmers for the same reason, but they won't admit that's why they like it. They'll claim to love .NET because of the power and flexibility. Not only are the .NET languages themselves allowed to be fully-featured, but the framework itself has tons of amazing functionality built right in. So much so that it's easy to miss some of it. When I needed to calculate an MD5 hash in my IM client, I went to the net, downloaded some C++ code and built myself a COM object (although I could have easily built a MC++ component, too) and then brought it into my app via interop (see what not being ashamed of the platform can do? : ). That was great, but this morning Peter asked me why I hadn't just used the MD5 functionality built into .NET. There's so much stuff in there that I missed it. As a community, we'll be digging into it for a long time to come.

    In the past, I had scoffed at the value of programmer productive over user productivity. My argument was that programmers are soldiers on the field of combat taking bullets and protecting the users at home. This was how I justified the complexity of C++, but measured it against the flexibility of the language and the performance of the produced code, and therefore the pleasure of the user. Don't get me wrong. We're still going to be using C++ for high-performance, shrink-wrap software for some time to come. Windows and Office XQ (or whatever they're going to call them) will still be implemented in C++. Client applications that cannot dictate their deployment environment, i.e. can't dictate the presence of the .NET runtime, will still be implemented in C++ or VB6. Most of the rest is going to be built in .NET without 12-24 months. Stand-alone corporate applications can dictate the presence of the runtime, as can server-side n-tier applications. Web-based applications can take advantage of the compiled and caching performance gains using ASP-style programming, will still enjoying the flexibility and power of ISAPI-style programming via .NET modules and handlers. Everyone in these spaces that works under Windows is going to be moving to .NET, especially the Windows Java programmers who already know the power of such a platform, but want easy access to their DLLs and their COM servers. The reason that people in these environments can now afford to move is that continued research in virtual machine-style environments and increase in machine power has brought about the first platform where ease of use for the programmer does not mean that the user has to suffer. Applications built with .NET are going to be fast enough and when it comes to ASP, they're going to be much faster than what we've had in the past.

    The combination of ease of use for the home-by-5 style programmer and the flexibility for the computers-are-my-life style programmer was so great in Java that tens of thousands flooded the Java conferences from the first year. Mix in a user experience that doesn't have to suffer from the programmers' choice of .NET and I finally get it.

    Be Your Own Teddy Bear

    Wed, 10/17/01

    According to legend, the TA office next to the Stanford computer science lab is guarded by a teddy bear. Before a student is allowed to consume valuable time asking a question of the TA, they must first explain it to the teddy bear. Apparently the bear is able to answer 80% of the questions that students ask, saving time for the TAs to play Unreal Tournament.

    I often feel like I act as the teddy bear for the COM community. I get several email messages a day from folks that consider the mailings lists (resources set up to answer just these kinds of questions) to be too slow, so they ask me directly. If I don't know the answer off of the top of my head, I often respond with the following phrase:

        "Can you send me a tiny, tiny project that reproduces the problem? --Chris"

    This, of course, implies that I will actually build and debug the project. And 20% of the time, I do. The other 80% of the time, by the time folks have reduced the problem enough to demonstrate it for me, they've already solved it, saving me the time (thank goodness).

    Knowing that this is the case, I recommend that you become your own teddy bear. A whiteboard is handy for explaining the problem to yourself and Microsoft development tools are now so handy that you can typically whip out a small reproduction project very quickly. These very activities will often solve the problem, but even if they don't, you've got a concise description of the problem and a small repro case to send to your friends or to post to the list.

    Flattery

    September 17th, 2001