The Learn/Measure/Build Cycle

Learn Measure Build Cycle

In preparing for Startup Lessons Learned next Friday I took a page full of notes during a conversation Eric Ries and I had about my keynote. I will wait for the conference to unleash the Big Message, but here is a smaller lesson that I found interesting.

Ordinarily we talk about the Build/Measure/Learn cycle (as in these slides from Ash Maurya, another SLL speaker). When Eric and I were talking, I realized that the loop is backwards.

From a programmer’s perspective, the loop is certainly correct. You write a program. You watch how someone uses the program. You learn something that you use to improve the program. I have had this experience many times. I have an idea for a program, I write it, I learn something.

Contrast that with the Lean principle of Pull: avoid the waste of overproduction by only creating based on demonstrated need. The customer orders a product, then you build it and deliver it. If that takes too long, make it take less long, don’t pile up a bunch of inventory in hopes that someone will buy it some day. Being able to instantly deliver a product no one wants is false economy.

I am working on two products right now that contrast nicely with respect to which way the loop runs. One product is a set of narrated screencasts illustrating test-driven development. For this product I’m running the loop forwards. I made a screencast, I saw how many people watched the unedited excerpt, I learned something about how many people are interested and how effective Twitter is as a marketing tool. Yes I learned something but now I’m at a bit of a loss. I’m not even sure what else I need to learn. I’ll make a couple more screencasts and then make the whole series available for sale. I hope they do well, but because I’m running the loop forwards I don’t expect to learn more about my audience until the casts are out there.

Contrast that with my other project, a poker-related game. Yes, I “primed the pump” with a very simple version of the game, but I’m now in a learning directed loop, running the cycle backwards. I start with an assumption, for example that I can make the game sticky. If the game is sticky, then people playing it will play several game per session and come back for multiple sessions. Now, what do I need to build to make it stickier?

The feeling is completely different between the two projects. With the screencasts I feel a bit lost. Yes, I know people are interested and I’ll sell quite a few units. However, I have no idea how to improve their value short of getting them out there and incorporating what people say into the next series of casts. It feels a bit like writing a book or the bad old days of writing a program for a year before trying to sell it.

Running the loop the other way, pulling the “build” from the needs of the learning, is much more energizing. I know why I am building when I build. I don’t create anything just grins. Programming’s still joyful, but it also has purpose. I know when to stop–when I’m ready to learn.

Here’s an exercise, gentle reader. Explain how to run the learning loop backwards for screencasts. One of the constraints is that people will only make one transaction per series, at least the way they are sold now.

Stuck with “NoSQL”?

While listening to the energetic and thoughtful discussion between the RIAK team and Tim Anglande I was struck by the difficulty of coming up with a better moniker than “NoSQL”. There is always a period at the beginning of a technology when it is understood in terms comparing it to the status quo–horseless carriage, wireless telegraphy, digital photography. When the technology is socialized (that is, widely understood and applied), these terms are replaced with positive terms–automobile, radio, imaging. NoSQL is still at the first stage, but I’m not sure there will ever be a clear term positively encompassing all the technologies it encompasses. Here’s why.

SQL vs Application

Here is the picture as of maybe ten years ago. The needs of almost all applications were covered effectively by row-oriented relational data stores. However, because these stores were mature, further improvements were discounted by the Law of Diminishing Returns.

Needs Plasticity

Here is the picture for applications that require frequent schema changes. The need for plasticity exceeds the ability of SQL to deliver, at least at a reasonable cost. I’ve worked on a life insurance system for 12 years that has relied on the ability to make daily schema changes. We wouldn’t have been successful with any SQL + ORM technology I know but our object database (Gemstone) handles such changes gracefully for the amount of data we need to manage.

The picture also shows where document-oriented databases like MongoDB or CouchDB fit in. There are things you can do with a row-oriented relational store that you can’t do with Mongo or Couch, but the key advantage they offer is the ability to rapidly change the shape of data. If that’s what your application needs, for example in a rapidly evolving startup, then a document store is a win.

Here is where the futility of defining NoSQL as anything but a negative space becomes apparent to me. There isn’t just one dimension along which SQL stores are inadequate for some applications, there are half a dozen. Different vendors address different subsets of these criteria. There is some overlap (I tried drawing several stores into this picture but it quickly became spaghetti), but the differences between the stores is large relative to their commonality.

To name the universe of all these products, you’d have to call them something like “better than SQL in one or two ways but worse in several others that don’t matter in some circumstances”. Shorten that to a phrase that fits on a T-shirt and you get “NoSQL”. I’m afraid we’re stuck with it for a while.

Creation Stories

I’ve realized for some time how powerful creation stories are in spreading ideas. Think of an idea that has power in your life or work. Do you know the story of the origin of that idea? If you don’t, does the person who introduced you to the idea? My experience is that I know the story or the person I learned the idea from knows the story. An idea only spreads as far as the story of its creation.

When I’ve had impact on software development, there has always been a story attached:

  • The group of us on a hillside in Colorado experiencing patterns first hand
  • Erich and I writing JUnit on a plane going to OOPSLA
  • The C3 project at Chrysler that spawned Extreme Programming
  • The workshop at Snowbird where we (well, actually I was pretty sick and didn’t do any of the work) wrote the Agile Manifesto

I was looking at the landing page of a two-person startup today and having trouble understanding the concept they were promoting. Their prose was obviously carefully crafted, but it was all written with abstract nouns–”we turn conversations into knowledge”. It didn’t make sense to me concretely. I suspected that the product might be applicable to my work but I couldn’t tell for sure.

My suggestion to the team was that they put their creation story on the landing page. If I could read about the moment they had their cool idea, they would have given me two valuable gifts–the emotional energy to keep working at understanding their idea and the beginnings of an intellectual understanding as well. To create their product they needed an epiphany, to be faced with a seemingly insolvable dilemma and for the resolution of that dilemma to come to them. If they told that story and I saw myself in the dilemma they presented, I would be pretty certain I was a good candidate for their product and I would be willing to work harder to understand it.

I would like to validate the use of Creation Stories empirically. Do Creation Stories work better than other forms of content in converting readers to customers? Here’s the deal. I would like to work with up to three teams who sell primarily through the Internet. You must be measuring your current conversion rate. Together we will write your Creation Story and then A/B test it. You must pay me for my help, but as I can’t even speculate on the value of this exercise I will trust you to set the price when the experiment reaches a statistically significant conclusion at what my help was worth to you. Assuming this idea really works well I will be selling this as a premium service. Please contact me if you are interested.

Smalltalk: Welcome to the Balkans.

Never blog when you’re mad. This is an excellent rule that I’m breaking right here.

For fun and education I started a MongoDB driver in Smalltalk. I wanted to learn about a NoSQL database from the ground (-ish) up and potentially provide something useful.

Step one: get it running in VisualWorks. Not a problem. I’ve used VW for 15 years. Lots of details to get right, but I’m a programmer. Details are slops in which I wallow.

Step two: find a customer. Again, not a problem. Someone has an application they would like to have populate a MongoDB database for later processing by other tools. Problem: the server is in Squeak.

Step three: port to Squeak. The pain begins. Just getting the code out of VW was a pain. I discovered Monticello, which is a nice concept for source control, sort of a Smalltalk-y version of Git (in the sense that they are both distributed SC systems). VW interface to Monticello is broken. Discussion with author resolves the issue. Code has escaped VW.

Loading into Squeak is no problem, but the Squeak programming tools are just too painful to use. Look no further for a shining example of the tragedy of the commons. Design requires inhaling–adding features, trying experiments, tweaking, going off in crazy directions–but it also requires exhaling–taking similar things and making them the same and deleting experiments that didn’t work out or at least moving them out of the core. Back in the olden days the limitations of the VM drove this, which is why the core concepts in Smalltalk were so refined. If you wanted space for your application you had to find a way to rationalize existing code.

On to Pharo. Pharo has a more coherent set of tools than the cacophony of Squeak but the base language/libraries are the same. The cleaner look was a relief although the paint splatters seem a bit indulgent. Whatever. I run the tests. They all break. Not a big surprise.

What’s broken? First, numbers. Syntax for literals. “16rff” in VW needs to be “16rFF” in Squeak. Sigh. No Double class because all floats are doubles, so Float is actually Double. No way to access the bytes in a Float. Then, dates. No built-in way to turn a Java timestamp into a timestamp. Different conversions required between Squeak and VW. Next, UTF-8 conversion. Grease to the rescue here. It’s the compatibility layer Seaside uses. Finally, sockets. At least this is no big deal. One class replaced by another. Except the Squeak version doesn’t support retrieving the position in a socket stream. Quickly fixed.

Now, I don’t particularly care for Java. Erich will tell you that I’m not productive until I’m swearing at Java. But credit where it’s due: the basics are portable. Numbers, sockets, strings, source code structures. You don’t have to worry about those moving from one platform or another. The vendors have found other battlefields on which to fight.

All the tests pass in Squeak finally. I’ve been making the changes in place, figuring I’ll make some kind of GratuitousDifferences class to capture the, well, you know. I load my code back into Monticello (I love SqueakSource, BTW–easy to use, free, what GitHub would have been if they’d stopped developing after a month. I told you not to blog when you’re mad.) I go to load into VW. Kaboom. The meta information is snarled. The monkey patches are gone. Merging does nothing sensible.

And that’s where I sit, blogging because I’m too mad to think. I’m not just mad because I’m stymied. That’s frustrating but not out of the ordinary. I’m a programmer after all. What I’m mad about is the gratuitous balkanization of Smalltalk. Here’s a language and platform that still has a lot to offer the programming world. There are lessons there about programmers being humans and users being humans that could be profitably absorbed by computing in general. And they won’t be, not if you can’t even move code between versions. Who would rationally invest in Smalltalk code if they weren’t already locked in?

I looked up Nash Equilibrium because it seemed appropriate. A Nash Equilibrium is (broadly speaking, look it up if you want accurate details) when none of the players in a game can change their strategy without losing something. The Mexican Standoff (as long as I’ve insulted Eastern Europeans I may as well insult our neighbors to the south as well) is a classic example. No one wants to be the first to lower their gun. The Smalltalk vendors seem to me to be in the same boat. Everyone has taken their “ANSI standard” Smalltalk in different incompatible directions, but to move towards compatibility would be a loss. Hence, no one is going to change.

The thing about a Nash Equilibrium is that what is rational from within the game can be absurd from an outside perspective. I’m calling bullshit on the state of Smalltalk. Vendors, you’re acting crazy. Have the tiniest possible core defined in terms of test cases. Build a shared library on top of that, implemented in terms of the core. Include numbers, collections, meta-objects, code structure, and code loading. None of this parcel/bundle/package/pundle/category nonsense. Compete on VMs, graphics libraries, and enterprise-y tools.

I know this can’t be a sensible proposal. There must be huge, insurmountable problems with it. After all, I’m too mad to think straight. But it would have made my job a lot easier today.

Written with all the love I can muster,

Kent

Field Annotations Unexpectedly Rock

I’d like to introduce you to an unexpected effect Saff and I ran into the other night while working on JUnit: annotations on fields are much more powerful than annotations on classes or methods.

Suites

JUnit 4 introduced the use of annotations to tag methods that were intended to be executed as tests. We extended this idea to annotating classes to tell JUnit to run them in a non-standard manner. For example, the old JUnit test suite functionality now looks like this:

@RunWith(Suite.class)
@SuiteClasses({
  AssumptionTest.class,
  ...
})
public class AllTests {}

I always found this syntax ugly and awkward, but I didn’t have a better alternative that was declarative, easy to write, and easy to read.

Annotated Fields: Rules

A recent innovation in JUnit is the introduction of rules. We noticed that may people who implemented custom test runners (like the Suite runner above) we over-served by having to subclass one of JUnit’s existing runners. The extraneous detail made learning how to write runners harder than it needed to be and most requirements from custom runner could be met with just a few entry points. All customer runner writers need is a way to insert their code into the flow of control that results in a test running.

We created rules, annotated fields that are called before and after a test is run. Here is a rule that writes to the console when a test is about to run:

@Rule public MethodRule logger= new TestWatchman() {
  public void starting(FrameworkMethod method) {
    System.out.println(method.getName());
  };
};

We were surprised by how flexible rules turned out to be. People began writing new rules for all sorts of unanticipated purposes. We had stumbled on a really useful API.

Categories: Take 1

For many years people have been asking JUnit to support categories, being able to choose subsets of tests according to a user-generated classification scheme. I thought (and still do) that this is properly the job of the IDE, but since we had implemented everything else higher priority we gave categories a try.

@Category(Fast.class)
public class B {
  @Test
  public void c() {}
}
@RunWith(Categories.class)
@IncludeCategory(Fast.class)
@SuiteClasses({ A.class, B.class, C.class })
public class FastSuite {}

By tagging the class B as belonging to the Fast category, the FastSuite, tagged to include Fast tests, will run the tests in B but not A or C.

The API is ugly but functional. As we got into the twisty little corners of the implementation, though, I had a hard time following what was going on (the true measure of a design is whether the main flow remains clear after all the corner cases have been accounted for). I was ready to quit programming for the life of an itinerant goat cheese maker when I thought, “Maybe the problem isn’t the implementation, it’s the API!”

Categories: Take 2

Putting our experience with rules to use, Saff suggested we try annotating fields instead of classes. Categories are an example of the more general concept of a filter:

@RunWith(Suite.class)
public class FastSuite {
   @SuiteClasses
   public Classes classes= new Listed(A.class, B.class, C.class);
   @FilterWith
   Filter filter= CategoryFilter.include(Fast.class);
}

We transformed both class annotations into field annotations, one to tell the suite which classes to run and one to tell the suite how to filter out unwanted tests.

Here’s the magic part. As soon as we had written this we could imagine several other ways of filtering tests–by recency of failure, by name, and so on. Implementing these changes requires no modification of the Suite runner. In fact, these changes don’t require any modification of the core of JUnit at all.

Likewise, using an annotated field opened up possibilities for retrieving the classes to run as part of a suite. Johannes Link’s handy ClasspathSuite can be recast as an alternative implementation of Classes above, along with a host of other ways to find the classes to run.

Taking a Step Back

I’m a big fan of declarative expression in programming languages. Annotations are superior to convention (like naming all test methods “test…”) for declaring intent because they can be checked by the compiler. The addition of parameters to annotations makes them even more expressive. However, annotations attached to elements fully determined at compile time (like classes and methods) are fundamentally limited.

The problem is the coupling between intention and implementation. An annotation attached to a class specifies both intention (i.e. “run this class as a test in a certain way”) with an implementation (“this exact class right here”). Conflating intention and implementation limits the flexibility and power of annotations.

Annotations on fields separates intention and implementation. The intention is attached to the field while the implementation is specified by the value of the field, which can vary at runtime. It is this separation, and the flexibility it buys, that is the secret behind rules and this proposed new test suite semantics and syntax.

I’m still getting used to annotations and what they are capable of. I know I’ll be looking for ways to annotate fields in the future instead of classes or methods if I have the option.

The Responsive Design Project so far: January ’10

In the Beginning

The second program I ever tried to write was a copy of the Star Trek simulator I had seen at the Lawrence Hall of Science. I had gotten through the BASIC language workbooks in a weekend. I had written a Roman numeral printer with no problems. How hard could Star Trek be?

I can remember my feelings sitting down at the teletype: anticipation, excitement, puzzlement, frustration, despair. I had no idea what to type. I knew the statements of the language, no problem. What I didn’t understand was design. I had no idea what elements there could be above the level of statements or how those elements could be related to produce the behavior I was imagining.

That day I just gave up and walked away. Over the next decade I slowly got a sense of what elements there could be in a program and how they could relate to each other. I acquired an aesthetic sense. I could take pleasure in a good design and feel discomfort in the presence of a poor one. Eventually I could take a problem and design software to address it.

But something was still missing. I couldn’t explain what I did when I designed. Little pieces like refactorings I learned, with a lot of collaboration, to articulate, but I couldn’t escape the nagging sense that design had hidden structure, like the plumbing and wires in the walls, structure that was critical to really understanding the process and product of design.

Revealing that hidden world of design is the goal of the Responsive Design Project. I want to understand and articulate the deep structure of software design. While the project has only just begun, I have some practical results I’d like to take you through briefly in this introductory article. And I’ll share with you the result that most disturbs and excites me:

  • Our illusion of control over software design is a dangerous conceit best abandoned.

In the Slightly Later Beginning

In 2005 I was invited to sit on a panel celebrating the 25th anniversary of the publication of Ed Yourdon and Larry Constantine’s Structured Design, the book that introduced the terms coupling and cohesion. I’d had a copy in my library since I’d used it as a college textbook, but, since I had used it as a college textbook, I hadn’t really read it. As I studied it in preparation for the panel, I realized that many of the questions I had about software design had been answered two decades before. This motivated me to make my informal study of design more structured and rigorous, and to communicate the results to a new generation of programmers. This was the official genesis of the Responsive Design Project.

Design is good. Design is central to effective software development. Programmers can add features steadily to well-designed software. Programmers can easily test well-designed software. Well-designed software is easy to tune for better performance. Most of the hard problems in programming turn out to be design problems.

But design has a dark side. While there isn’t a single best design for any system, there are many poor designs for that same system. The more experience a programmer has, the more design ideas he knows. The temptation is to put these design ideas in the system now because you just know you’ll need them eventually. Over-designing early leads to delaying feedback from real usage of the system, makes adding features more complicated, and makes adapting the design more difficult. By the same token, under-designing makes adding features more complicated, increases defects, and makes adapting the design more difficult.

The word “responsive” in the name of the project reflects this need for balance. Some design needs to be done in advance of coding, but over the life of the project most design will be done in response to the changing needs of the system and the changing and growing understanding of the developers.

The project is based on three parallel tracks of inquiry:

  • Quantitative. Measure real designs and see how they behave “by the numbers.”
  • Introspective. Carefully watch my own practice of design and draw lessons from the patterns I find.
  • Pedagogical. Teach software design and draw lessons from the students and their subsequent practice.

The Tour

Here is a quick overview of the lessons I have learned so far. Each topic deserves an essay of its own, or even a book chapter (say, you don’t know anyone who publishes technical books, do you?).

Beneficially Relating Elements. Designs are made up of elements that relate to each other in beneficial ways. Looked at actively, designing is creating and deleting elements, creating and deleting relationships, and increasing the benefit of existing relationships. Elements contains elements and so on down (and up).

Design is Fractal. There is no fundamental difference between implementation, design, and architecture. They are all a matter of beneficially relating elements. Learn to bounce between levels of abstraction. Most design takes place at a single level of abstraction but big advances often come as a result of rearranging the levels.

Safe Steps. Resolve the tension between efficiency and safety in favor of safety, then learn to take small, safe steps fast enough that from the outside it looks like you are flying.

Isolate Changes. Before making a change, isolate the area to be changed from the rest of the system so you can change an entire element at a time. For example, before changing a part of a procedure, extract the area to be changed into its own procedure. Make the change, then inline the changed sub-procedure if appropriate.

Embrace Ambiguity. Half done with a change and not sure what to do next? Stop and deploy (you can do this if you are working in safe steps). Complete the change when you know what to do.

Cultivate Confidence. Master your tools. Your feeling of mastery will improve your cognition.

Cultivate Humility. Try tools or techniques you aren’t comfortable with. Being aware of your limitations will improve your effectiveness.

Exploit Symmetries. Divide similar elements into identical parts and different parts.

Trust Succession. Design simply today, knowing you can add complexity needed tomorrow.

Design Is a Team Sport. The social side of design is as important as the technical side. Learn the skills needed to communicate and understand designs.

Play with Words. Recasting a design using a different metaphor can revolutionize your understanding.

Play with Pictures. Explain a design using hand-drawn pictures. Ask others to do the same. Design benefits from your whole mind: symbolic, verbal, visual, kinesthetic, conscious and unconscious.

Clear Strategies. All design changes use one of four strategies:

  • Leap. Make the new design and use it immediately.
  • Parallel. Make the new design and run both new and old simultaneously.
  • Stepping Stone. Create a platform to bring the desired new design within reach.
  • Simplification. Only implement part of the design now and add complexity bit-by-bit later.

Inside or Outside. Change the interface or the implementation but not both at the same time.

Toss It. Checkpoint often. If you get confused, learn what you can and revert. Now. Beware the sunk cost fallacy.

Keep It. If the system is working and creating value, keep it and improve it.

Start over. Sometimes the constraints of the problem plus the constraints of the existing system are just too much to handle at one time. I prefer incremental improvement, but sometimes it’s best to just wipe the slate clean and start over.

Both. Faced with design alternatives without a clear winner, do it every way. Just coding each alternative for an hour is more productive than arguing for days about which is better in theory, and a lot more satisfying.

Suit Design to Needs. A design strategy intended to maximize feedback from rapid changes looks very different from a design strategy intended to increase value by reducing cost. Both are appropriate at different phases of a system’s lifecycle.

Use Tension. There will always be tension between designing better and delivering sooner. Learn to fuel your creativity from this tension.

Conclusion

Many metrics in design are power-law distributed. For example, if you graph a histogram of the cyclomatic complexity of the methods in a large system on a log-log graph you get a straight line. In other words, there are many very simple methods and a few very complicated ones.

This same distribution is found in many measurements from nature—the intensity of avalanches, for example. This leads me to the most exciting and disturbing lesson I have learned about design so far:

  • Design is not a rational process.

Much as we like to think we are making design decisions, much of the structure of our systems emerges from the nature of the problem and the nature of the tools we use. Our designs shape us as much as we shape our designs. Insisting that we as designers are “in control” is counter-productive, leaving us wasting energy trying to act against nature. The challenge is to embrace responsibility and at the same time take an appropriate role in designing. Learning to achieve this balance is the next goal of the Responsive Design Project.

Why NoSQL Now?

Why have NoSQL database reached the tipping point now? Almost twenty years ago I lived through the attack of the killer object databases. While they had some lovely technical superiorities (and I still make part of my living helping maintain a Gemstone/Smalltalk application), relational databases were able to beat object databases in the market. It wasn’t time.

Now, though, seemingly suddenly, alternative data models are all the rage. While my narcissistic programer self would love to believe this had something to do with technical superiority, experience argues otherwise. Instead, if you want to understand technical change it’s more effective to follow the money.

I was talking to a developer of a cloud-deployed application (hi Patrick, love that BrowserMob.com!) and our design discussions quickly focused on money. SimpleDB is great for high-transaction rate storage, but it’s too dang expensive for reporting. A special-purpose database just for reporting makes sense. It’s worth extra programming to reduce operational costs (the classic capex/opex tradeoff familiar to telecom engineers).

Some Made Up Numbers

Here are some made up numbers (thanks @jkordyback) to illustrate the dynamic (adjust the numbers for your actual situation). Say you have a database from a commercial vendor. It costs you annually:

$50K (license) + $1.5K (electricity) + $1K (capital) = $52.5K

If you need more performance it makes sense to get beefier hardware:

$50K + $2K + $3K = $55K

The performance advantages of an alternative data storage paradigm (column-oriented, document-oriented, key-value, map-reduce) don’t justify the additional cost and complexity.

Eliminate the license and the cost of electricity becomes a huge percentage of the cost of a database. (EC2 is basically a really complicated way of charging for electricity.) Any technical advantage that reduces energy usage turns directly into profit. Your database now costs you:

$0 + $1.5K + $1K = $2.5K

Buying beefier hardware is a giant bump:

$0 + $2K +$3K = $5K

What if you can avoid the hardware upgrade by shifting to an alternative database? Factor in internet-scale applications so you’re multiplying all your costs by 100 or 1000. The engineering required to shift to a different store or to keep multiply stores in sync vanish in comparison to the operational expense savings (1000 servers for illustration):

$0 + $1500K + $1000K = $2500K

Improving performance with hardware:

$0 + $2000K + $3000K = $5000K

Versus switching to a different store:

$0 + $1500K + $3000K + $500K (engineering cost) = $4000K

Implications

There are several things that catch my eye in this picture. One is that when I was going to school we were always taught, “In the olden days of computing, computers were expensive and programmers were cheap. Now it’s the reverse. Therefore…” We are back to the future. At internet scale, programmers are (sometimes) cheap compared to the cost of electricity. That’s a pretty fundamental assumption to change. I’m sure we haven’t fully digested the implications.

Another is that the technical advantages of alternative stores translate directly into economic advantage. If I was a big database vendor, I’d be diversifying away from reliance on big-iron licenses, say by buying a hardware company (oh…) or running a variety of storage models on my cloud (double oh…) Again, I’m sure we haven’t fully digested the implications of this shift.

In spite of the roughness of the numbers above, based on this I feel justified in my gut feel that the row-oriented relational model we’ve lived with for 30 years is about to shatter. Look for opex optimization to become an increasingly important topic for engineers. Look for vendors, both software and services, to deliver further opex improvements. Where it goes from there isn’t clear, but it certainly will be interesting. The time has come.

The “financial” “models” above are just thinking tools to look at trends. I’d love to see some real numbers and trends to validate the qualitative conclusions I’ve already jumped to.

Write Your Own Fan Letter

During an exchange on the lean startups mailing list, one of the participants was having a hard time articulating the value of the vision he had for his proposed site. It was clear that he was passionate about what he wanted to build, that he was completely convinced about its value. The problem was that he couldn’t communicate the value to others.

I’ve been in a similar position many times, having a vision of where things were going next and how cool it could be but not able to communicate it clearly. I know three things about this situation 1) it’s incredibly frustrating for me, 2) it’s at least as frustrating for the people I’m trying to talk to, especially when I won’t shut up, and 3) I’m often wrong.

I’ve tried a variety of tactics to get out of being stuck. Just making the dang thing is one good way to clarify the situation. I wondered, though, if there was a less wasteful way for him to clarify his vision (I’m a geek and I don’t mind failing when I make something because making it is so much fun).

I borrowed an idea I’ve used often, speaking back from the future, and massaged it a bit: write a fan letter to yourself, written in the voice of a deliriously satisfied user. Here was my example:

Dear Match.com,
Just writing to say how pleased I am with your service. I live in a small town and was unable to find dates. A friend told me about Match.com. The survey process required me to take a careful look at myself. Three days later I had made contact with 5 women in my area. After initial dates with two women, the third one was clearly a, well, match. We dated for six months and are now planning our wedding for this spring. The $40 I spent with you was the best investment I’ve ever made in my life.
Yours truly,
John Q. Geek

Visions start out in your head but they don’t matter until they touch someone else. Finding a path by which visions can create joy is one of the many challenges of entrepreneurship. The purpose of writing your own fan letter is to prepare your mind to bridge the gap between vision and effect. When you can imagine how one person’s life is changed by your vision, you are ready to move forward.

Not My Money Any More: Lessons from Poker 4

Here is my first lesson from poker. I take that back. My first lesson from poker is when two strangers ask if they can join the game, lose a little all night, then offer to cut the cards for $100 as the game is breaking up, count the deck before and then after they turn up the ace.

Okay, so this was my second lesson from poker: as soon as it leaves my hand it’s not my money any more. The day after the game I was incredibly frustrated. I’d lost and lost all night long. I kept rebuying and losing, rebuying and losing. All I could think about was when was the next game so I could win my money back.

Over the course of the next week I became obsessed by that thought: I was going to win my money back. At the same time, a part of me was standing off to one side say, “Excuse me, hello, this doesn’t make any sense.” At some point I figured out how to articulate what was wrong with my thinking–it wasn’t my money. It wasn’t my money as soon as someone else won the hand. In fact, it wasn’t my money as soon as I put my bet in. I gave my money to the game, the game gave the money to the winner, and that was that. I couldn’t win my money back because it wasn’t my money.

Peace. Sometimes obsession works like that. You figure out what’s wrong with your thinking and the cycle just stops. This was one of those times. It wasn’t my money. I couldn’t get it back, because it wasn’t mine. The next time I played, I was just playing. I started with $20 and went from there.

Many of you will have recognized the Sunk Cost Fallacy. Money already bet is gone, sunk. It makes no sense to factor it into your decision making. I knew about the Sunk Cost Fallacy, but I wasn’t spotting it in my own thinking.

The same situation comes up all the time in programming. You have a long refactoring session, every step of which is perfectly safe. Then you run the tests. A test breaks. What should you do? What should you do if the error isn’t obvious? What should you do if the error isn’t obvious and you have been refactoring for a minute? An hour? A day? Does the amount of time invested have anything to do with how you proceed?

My experience is that the right thing to do in a situation where I don’t know what I did to break the tests is immediately return to my last known green state and re-run the tests. Then I begin refactoring again and run the dang tests every step. But, and here’s the irrational part, the longer I’ve been refactoring, the more tempted I am to press on. That’s the Sunk Cost Fallacy at work.

The longer I’ve been refactoring, the less well I remember all the steps, the harder it will be to spot the error, the greater the value of just starting over. The harder it is to start over (emotionally), the more valuable it is to start over.

It’s not my time any more. Have I been refactoring for a minute? An hour? A day? Doesn’t matter. It’s not my time any more. I’ve given it to the program. It’s gone. What I should do now should not be influenced by the magnitude of time I already have invested. It’s not my time any more.

As I was writing this I occurred to me that I’ve been guilty of a variation on the Sunk Cost Fallacy with JUnit. If you’ve been reading this blog for any length of time, you’ve heard me whining about not having found a business model to turn the success of JUnit into revenue. The faulty reasoning goes like this: JUnit has created all of this value in the world (billions of dollars by my envelope calculations) and I haven’t received any of it.

So what? If JUnit hadn’t created any value at all so far but was still in the same position, what should I do? Exactly the same as if it had created a million dollars of value or a billion. It’s the Sunk Benefit Fallacy. What’s past is done. It’s not my benefit. All that matters is the current situation. Any energy or thought I expend on the past will only muddle my thinking.

So here’s my resolution. I will think about the current state of developer testing, figure out the trends, and get ahead of the curve. That’s how I will make a living from JUnit. Oh, and I’ll be sure to count the deck, or better yet, not gamble with strangers.

The Pleasure of Pattern: Lessons from Poker 3

Studying poker has helped me crack a long-standing (maybe 20-year-old) puzzle for me: why are so many programmers musicians? I’ve sang and played guitar and various other stringed instruments since I was eight and I started programming at 13, so I’ve lived this dual life for a long time, but I’ve never understood it. I’ve heard explanations like “music is mathematical and programming is mathematical”, but I was never satisfied with them because they didn’t match my experience. I don’t think “mathlich” when I’m programming. Here are the three threads–programming, music, and poker–and how they came together for me.

Programming

One of the transformative experiences of my young life came in high school when Mr. Burishkin (hi Dave!) got mad at our algebra class (this was fairly common) and assigned us all 40 trig identities in the book. Usually we’d get half or a third of the exercises in a given set. Here was a big pile of work I couldn’t get out of easily.

For once I did the right thing and decided I would just plow through the whole stack. The first few were hard. I had to sweat to figure out how solve them. Each one posed unique challenges. At this rate the assignment was going to take me hours. Somewhere around half way through the assignment, though, a door opened in my mind. I’d look at a problem and see it in terms of the problems I’d already solved–I can split this in two, transform part 1 into this and part 2 into that and I’m done. I blew through the rest of the assignment in minutes, eager to solve more.

Not could I solve the problems quickly but I enjoyed the process. Every time I transformed the chaos of the original problem into a pattern I knew how to handle, it was intensely satisfying.

I have the same feeling of satisfaction with many programming-related tasks–when I see a big refactoring in terms of a succession of smaller refactorings, when I see a big task in terms of independently verifiable sub-tasks, when I see a big feature in terms of a succession of features each of which delivers value–at all these times I feel good.

Music

For thirty years I’ve played off and on with my musical partner Curtis Wright. We play American folk music. While I’ve enjoyed playing with many people, Curtis and I share a deeper level of musical communication than I’ve experienced with anyone else.

We don’t plan song endings. We end every song differently every time. Here’s how it works. When we’re really “on”, I will hear him play some interesting phrase somewhere in the middle of a song and something will click in my mind. There’s no explicit communication at that moment though–no nod, no eye contact, nothing. When we get to the end of the song, I will play that phrase as a tag and he will too, in perfect time. It is the most exhilarating feeling because we’re so completely at risk. If we chose different phrases to play, it would sound terrible and we’d look like fools. When we re-invent the ending and pull it off, though, it’s absolutely electric, both to play and to hear.

This is the most extreme example I have of matching patterns in music, but music is full of patterns–what makes a phrase, what makes a chord, what rhythm or rhythms are going on, what style should this piece be played in, backing up an unfamiliar tune by ear, and on and on. I enjoy music because I enjoy those moments of discovering the patterns in a piece. When I see a pattern, I feel satisfied. Woodshedding (practicing physical skills) is necessary to be able to take advantage of patterns when I see them, but I don’t enjoy it the way some people do. Experiencing music, for me, is experiencing patterns.

Poker

When I started studying poker I didn’t have any particular expectations, I was just interested. One of the basic problems in poker is having a more accurate belief about your opponent’s hand than they have about your hand. Their patterns of betting give you clues. At some point you say, “He must have just gotten a second queen,” because how he is playing doesn’t make sense otherwise. When I’ve guessed right, I noticed that I have a moment of the same kind of emotional pattern matching satisfaction that I have when I’m playing music or programming. That’s when I made the connection–this feeling is familiar, it happens when I program and when I play music.

There’s my answer: talent for music and programming occur together because accomplishment in each relies on enjoying seeing patterns. See a pattern, feel good, look for more patterns.

The bigger the stakes and the bigger the pattern, the greater the satisfaction. I won’t play poker for much money because I’m not any good at it. However, I experience more satisfaction when I see big patterns in programs (what some people call “architecture”) or big patterns in music (the so-called “long phrase”).

I suspect that my chaotic early life left me with a brain wired to crave moments of order and feel good when I find them. That and the innate ability to see patterns led me to activities where I got frequent mental rewards. I’ve just identified this connection, so I haven’t done any background studies into the neuro-science of pattern matching. From my experience I would guess that the same kind of dopamine release that accompanies other pleasurable activities happens in my brain when I match a pattern, musical or programmatical. I’d also like to see an fMRI to understand the neural activation patterns at such times and see if programming, music, and poker all really have similar physical neurostructures.

My partner Cynthia Andres is also a pattern matcher, but she matches patterns of human behavior. She has a good sense of what people are thinking or feeling based on cues that are totally invisible to me. I wonder if there are any studies correlating skill at reading people with skill at music. Are psychologists musicians the way programmers are musicians, or are musical and programming pattern matching similar in a way that musical and social pattern matching aren’t?

Another question this brings up for me is the evolutionary psychology of this kind of pattern matching. What is the evolutionary advantage of being able to match abstract patterns? Assuming it increases evolutionary fitness, what is the cost of it that kept it from becoming universal (I suppose my kids could provide a long list in answer to this question)?