spout

April 11, 2005 spout

My First Week on an MS Product Team: Wallowing

April 11, 2005 spout

My First Week on a Microsoft Product Team: Wallowing

Last week was my first week on my new team. A lot of interesting things happened, some of which Don has already mentioned. For me, two especially interesting things happened. One, I found out why I was hired, in spite of my preference to work from kitchen most of the time, even though I’m working on a product group (which typically avoids my kind unless they’ve already worked for the team for a long time) and even though I’m working for a manager that’s never had a remote employee (he doesn’t even run IM!). Don’t get me wrong; it’s not like a skated through the interview process w/o passing.” But passing” isn’t enough when you work in a shower optional” environment (my house, not Microsoft : ). My team needs people with a skill that I’ve never seen applied to product development. Most of the people that have this skill are either a) already busy shipping Indigo or b) marked as a target (some of you should feel the laser sights on your forehead : ). The skill is the thing that allows me to write books and articles in my own special way. My team has a name for this skill; it’s called wallowing.”

For my team, the ability to wallow” means the ability to dig into a discipline, any discipline, and wallow like a pig in the mud” in that new discipline, forming questions, getting to the root of things, gathering fragmented truths together into wholes, communicating the truths to each other, gaining intuition, and generally spending time understanding the space without first coming to firm conclusions about what it is that we’re actually going to build. This skill is by far the most important thing I learned at DevelopMentor. The popping” sound I got in my head when I finally figured out COM is something that I’ll never forget (mostly because my head stopped hurting after 6 weeks of hurting very much) and it’s served me well over the years. For example, I wrote my WinForms book not because I had a ton of real-world experience” as my Amazon reviews claim, but because I knew very little about WinForms and was interested in learning. I wallowed in WinForms for 9 months, writing articles and an instructor-led short-course before ever writing a single word in my book. Once I’d wallowed, however, I was able to write the book itself in 5 months.

So, while I’ve used to wallowing as a way to produce talks and prose, it’s not a technique I’ve ever applied to product selection. In the past, I’ve come to a team where the goal was very clearly known, although the details were still up in the air (often ’til they were discovered as coding problems). I’ve even started my own software organization from scratch, but only after the core vision of what needed building came to me whole and I’d already built the prototype. However, with my new team, we’ve got a group of folks actively wallowing in a space, figuring out the right thing to build. This led to some initial frustration on my part.

Actually, frustration is too weak; for the 3 days of my employment, I was a drooling idiot with no hope of recovery. I’m used to not knowing stuff (that’s when the wallowing behavior is triggered), but I’m not used to not knowing what I don’t know. The reason that I was so frustrated was that I didn’t know my team was wallowing. My team has already been working together in this problem space for months. They’ve already put together a prototype and showed it to BillG. This evidence made think that the team already had a firm vision of what they were building, so I was in coming-to-a-team-to-help-build-a-known-product-mode as with every single product team I’d ever been on or heard of.

Firmly in this mode, I spent my first 3 days in architecture meetings, brainstorming our way through the main issues of our product.” At each meeting, it seemed like people had a firm idea of what they were building, because the items on the brainstorm list flowed like water from everyone but me. To give myself some ground on which to stand, I kept asking whether we were going to cover this customer scenario or that one and the answer would always be yes.”

This went on for three days and each day I felt like I knew less about what we were doing. Instead of drawing up a plan to build a v1 settlement on the moon, I felt like we were listing the issues associated with covering the entire surface with a 10-story city. My head was swimming. How could a brand new team be targeting that kind of scope? What the hell had I gotten myself into?!?

I’m not the kind of person that keeps frustration to myself. I spent a good deal of time trying to express my despair to my boss and my new team mates, but it took me 3 days to be able to wind back my assumptions enough to be able to ask, Do we even know what we’re building?” The answer that shined light into my gloom was no, we’re wallowing.”

And suddenly, all the conversations made sense. When they kept saying yes,” they meant yes, we’re still considering that possibility.” We were discussing enough issues to cover the surface of the moon not because we were going to do that in v1, but because we were still figuring out the right place and kind of settlement to build. We’d picked the moon and we’d put up a tiny shed to see what it was like to live there, but we hadn’t yet figured out what the next wave of settlers would need. And because we didn’t want to die in the process or kill that next wave, we were going to spend some real time exploring to make sure we were proud of our first city.

This process was a revelation to me. In the small to medium-sized software engineering projects in which I’d been involved to date, this kind of product planning was outside of my experience. I mean, even when I plan to wallow in the implementation details, I’ve never once wallowed in the issue of what to build. When I picked my WinForms book, I didn’t survey the .NET developer landscape for their needs; I just picked something I was interested in. I got lucky, but in the case of other projects, I have been less so (and sometimes expensively, spectacularly less lucky).

I told my sister-in-law this story and she was all ready to be upset for me. You mean, they never told you? You signed up to do product development and they don’t even know what they’re building?” she asked. I told her that I wasn’t upset at all. In retrospect, I was told that my team was wallowing, it’s just that my preconceptions about what a product team does at Microsoft blocked it out.

Further, this way of figuring out what to build is one I’m looking forward to. I’ve never been any good at this part of the product construction process. In fact, I once drove 2 hours north and cajoled Eric Sink into driving 2 hours south so that I could ask him how to answer this very question (micro-ISVs sound cool, don’t they?). His advice was fail fast.” That’s good advice and, having talked to my new boss, it’s something we’ll be doing, but we hope to do it while exercising wallowing as a product selection technique.

The second thing I learned this week is that, while I didn’t know this ’til after my 3rd day, my team is still wallowing. I told my sister-in-law that I wasn’t upset at all. I love wallowing. : )

April 9, 2005 spout

Geeks Rule and MBAs Drool

Eric Sink takes a long, long time to say the following (learn to let go, Chris [1]…):

The following is an example of one of the most common questions I get from developers who are creating a brand new software company:

Where can I find a partner to be a co-founder and handle the business side of things?

My answer: Don’t.

Do all that stuff yourself. You need the experience anyway. If you really want a partner, don’t find an MBA, find another geek like yourself. Don’t be afraid to allow your company to be very developer-centric for a very long time. By doing it this way, you’ll avoid a lot of problems and you’ll learn a lot.”

Like agile programming, Eric has just given us permission to do what we want to do anyway. Wahoo!

[1] One of my favorite duties at MSDN used to be developmental editing on Eric’s writing. I used to love how he’d work certain things into his piece, e.g. the thing my 9-year old son posts on his door, modulo s/Geeks/Boys and s/MBAs/Girls.

April 1, 2005 spout

My First New Job at Microsoft

Here. The one where I stop working for MSDN.
April 1, 2005 spout

My First New Job at Microsoft

Today’s my last day at MSDN. I will no longer be content strategizing for Longhorn/WinFX or smart clients or acting as liaison between marketing, evangelism and the product teams internally and developers externally. And I’m really going to miss it. MSDN took a flier on me being a successful Microsoft employee in a culture that doesn’t much like remote folk and made a very comfortable home for me. I could’ve gone on for a long time in that role.

Still, I felt another calling. At Microsoft, it seems like all of the action is with the product teams. To come to Microsoft as a software engineer and not work on a product team seemed like starting with the Yankees but never getting out of the dugout.

So, on Monday, I start in DSG (the Distributed Systems Group) aka the team that owns Indigo. I’ll be are looking at ways to extend the notions of modeling that we’ve incorporated deeply into the stack and make them more general” (or so my new boss says). I can’t tell begin to describe how lucky I feel. Not only do I get to be on a real product team, still mostly from my house in Oregon, but I get to work on a very juicy problem. Further, I get to do it with Oliver Sharp, one of the prime movers on the Indigo team, along with a growing group of other people way smarter than I. It reminds me of the heyday of a certain training company with which I once had a deep relationship.

Two weeks ago, Oliver sent me a list of 10 fun computer sciency things to dig into that could take months. Last week I was helping the team get ready for a BillG review. This week I was trading emails with the team and a Sr. VP on the direction of the market and how it affects our product plans. Is this what it’s like for an addict that’s given up their habit to take it up again? If software engineering is wrong, I don’t want to be right! : )

March 30, 2005 spout

Leaders and Legacy

Here. For an internal thingie, I was asked to write a short bio, define what I think a "leader" is, describe my target legacy and list my biggest source of pride. This is what I came up with.
March 30, 2005 spout

Leaders and Legacy

For an internal thingie, I was asked to write a short bio, define what I think a leader” is, describe my target legacy and list my biggest source of price. This is what I came up with:

I’ve been pretty much everything you can be in the IT industry including author, speaker, consultant, conference organizer, grunt in a start-up, CEO in a start-up, developer, tester, documenter, etc. I’m currently a content strategist for MSDN in the areas of WinFX/Longhorn and smart clients. I’m passionate about building products to make people happier, whether that’s because they’re more productive or because I’ve solved some hard problem or just because they lean back and say cool!” My biggest regret is that I’ve never yet been on a product team at Microsoft; to get the full experience, someday I need to do that! After that, I can retire and write novels from coffee shops around the world. : )

A great leader is someone that inspires you to do things you didn’t even know you were capable of doing.

The legacy I’d like to leave behind is that people can look back at their interactions with me and think that I helped make their lives better, whether it was an answer to a tough question or an insight that they hadn’t had before or a comment that tickled their funny bone.

The biggest source of pride in my life is the family I’ve built with my wife and two sons (the Sells brothers, whence the name of my web site came: www.sellsbrothers.com).

March 30, 2005 spout

I can feel Avalon changing me…

I can feel Avalon changing me…

I’m writing a tiny little application for my writing on ClickOnce in Avalon. In fact, to demonstrate ClickOnce, the app hardly matters, so I picked something really simple: an excuse generator. I didn’t even have to make up the excuses, as I stole them from an office gag gift two years ago and wrapped them in an excuse web service (which is a whole other story : ).

Binding to Data Defined in Code

The idea was to have an array of excuse strings like so:

public partial class Window1 : Window {
  static string[] excuses = {
    "Jury Duty",
    ...
    "It's Not My Job",
  };

public Window1() {
    InitializeComponent();
    this.DataContext = Window1.excuses;
  }
  ...
}

Once I had the collection of strings, I make them available for binding by setting them to the DataContext of the main window and the rest of the code would simply be a matter of binding a TextBlock to the current excuse like so:

<Window ...>
  ...
  <TextBlock TextContent="{Bind Path=/}" />
  <Button x:ID="newExcuseButton">New Excuse</Button>
  ...
</Window>

By binding the TextContent property of the TextBlock to a Path of /”, I’m explicitly saying don’t try to dig into each object in the collection looking for sub-properties, but binding to the item itself.” Initially, the TextBlock will show the first item in the list:

When the button is pressed, I change the output by selecting a random item from the collection and setting it as the current” item in the collection:

Random rnd = new Random();
void newExcuseButton_Click(object sender, RoutedEventArgs e) {
  ListCollectionView view =
    (ListCollectionView)Binding.GetDefaultView((IEnumerable)Window1.excuses);
  view.MoveCurrentToPosition(rnd.Next(view.Count - 1));
}

By grabbing the view for the excuses collection, I can do a number of things with it, including move the current item in the view to some specific position. When I do that, the data bound TextContent property of the TextBlock will be updated to show whatever is current:

So here’s the first thing that I’m notice that I really approach differently in Avalon: the data binding hammer is almost always the first tool I reach for in the programming box. In the old days, to write this app, I’d set the TextContent property directly in code. Now, I don’t even think to do that. Instead, I’ve got data and a property to set, so that’s data binding.

Binding to Objects Defined in XAML

But wait!” I hear you howl. What about internationalization?!?” I know. Hard-coded data in the source code is a bad idea. So where does it go? Into the XAML itself, of course, so that anyone working on the UI, whether for an English-speaking country or not, can add new items, port them to another language, etc. How to do it? Well, since XAML is an XML dialect for describing object hierarchies, I could define a new type (roughly):

class Excuse {
  string value;
  public string Value { get { ... } set { ... } }
}

class ExcuseData : List<Excuse> {
}

Then I could write my excuse data as a hydration of objects using the ObjectDataSource (roughly):

...
<Window.Resources>
  <ObjectDataSource x:Key="ExcuseData">
    <l:ExcuseData>
      <l:Excuse Value="Jury Duty" />
      ...
      <l:Excuse Value="It's Not My Job" />
    </l:ExcuseData>
  </ObjectDataSource>
</Window.Resources>
...

The XAML inside the ObjectDataSource will create an instance of the ExcuseData type, adding an object of type Excuse for each <Excuse> element, setting the Value property of the object using the Value attribute from the XAML. With the object data source, I can create a little data island” in the middle of my app where the list of excuses can be poked and prodded without touching the code.

Binding to Data Defined in XAML

Still, why go to the trouble of defining my own custom data type, which doesn’t have any behavior to speak of, when I’ve got the universal behavior-less data type — XML? I can use the XmlDataSource without any custom type at all:

<Window.Resources>
  <XmlDataSource x:Key=“ExcuseData” XPath=“/Excuses/Excuse”>
    <Excuses xmlns=“”>
      <Excuse>Jury Duty</Excuse>
      …
      <Excuse>It’s Not My Job</Excuse>
    </Excuses>
  </XmlDataSource>
</Window.Resources>

You’ll notice that the XML looks almost exactly like the object data source, except that instead of using an attribute to keep the juicy bits, I use the content area itself to store the data, very like the initial array example (I could have used XML attributes, but it seemed overkill in this case). One other interesting bit is that XPath of the XML data source itself. It defines the bit of the data island from which I’m pulling the data. If I had used /Excuses, the data collection would have had a single item with a bunch of children. But using /Excuses/Excuse, I’m exposing the children directly.

To use the XML data source, I need to set it as somebody’s data context in the hierarchy of controls and bind to it:

<Window ...>
  <Window.Resources>
    <XmlDataSource x:Key="ExcuseData" XPath="/Excuses/Excuse">...</XmlDataSource>
  </Window.Resources>
  <Grid ... DataContext="{Bind DataSource={StaticResource ExcuseData}}">
    ...
    <TextBlock ... TextContent="{Bind XPath=.}" />
    <Button ... x:ID="newExcuseButton">New Excuse</Button>
  </Grid>
</Window>

I should note that in future bits, I’ll be able to set the grid’s data context to {StaticResource ExcuseData} directly, but in the March 2005 CTP Avalon bits, I have to actually bind the data source to the data context in a double bind that blows my mind.

More importantly, notice that instead of using a Path to get to the data I want, I use an XPath. This allows me to further refine the XPath statement provided as part of the XML data source itself. However, since I don’t want to refine it any further, I use the XPath statement that says just use the content of each of the elements.” You’ll notice that I used .” in the XPath statement to provide this meaning instead of /” as I did in the case where I was using an object Path. The two syntaxi look the same, but are very different and you’ll want to watch yourself switching between the two.

Anyway, with the data moved to the XAML along with the UI and the binding logic, my actual code boils down to only the following:

public partial class Window1 : Window {
  Random rnd = new Random();

  public Window1() {
    InitializeComponent();
    this.newExcuseButton.Click += newExcuseButton_Click;
  }

  void newExcuseButton_Click(object sender, RoutedEventArgs e) {
    IDataSource dataSource = (IDataSource)this.FindResource("ExcuseData");
    ListCollectionView view =
      (ListCollectionView)Binding.GetDefaultView((IEnumerable)dataSource.Data);
    view.MoveCurrentToPosition(rnd.Next(view.Count - 1));
  }
}

So, this is really only a few lines of code, one to hook up the button event handler, one to find the excuse data from the window resources, one to get the view on the excuse data and one to move the currency pointer to some other random spot. The actual display of the data is left to the data binding code (which somebody else gets to maintain).

One other thing worth noting is that I had defining event handlers in the XAML. Even when it’s me writing both the XAML and the code, I don’t like the XAML making demands on the code. If the XAML handles an event, e.g. with an event trigger, than that’s fine, but don’t make requirements of the code form the XAML. Instead, provide hooks for the code to do its work, e.g. the x:ID on the ExcuseData and the TextBlock are both used in the code, but neither requires anything of the code. If you’re going to separate the presentation from the logic, this is the kind of thing you’ll want to think about.

Where Are We?

Two things I’m finding that Avalon has changed about my thinking. The first is that data binding makes itself into even trivial Avalon applications and its presence is appreciated. The second is that I want to push as much stuff into XAML as I can. Keeping the data separate from the code makes a bunch of sense and, for my trivial application, keeping the data inline with the rest of the UI was very useful. It allows for easy maintenance and localization while pushing as much of my application into declarations and out of imperative statements. The more I can tell the computer what I want instead of how I want to accomplish it, the better off I am.