8 June 2012

Buy, don't build. But if you build, also sell.

Here's an additional thought to my last post. The model from which I inferred this rule is Google. Google famously used a variant of the "buy, don't build" rule when they build their data centers out of many standard computers instead of big customized ones. They also use standard Linux and its tools for many tasks. But Google also very often makes exceptions to this rule. There's the Google Collections (now Guava) libraries replacing of standard Java collections, there's GWT to write JavaScript in Java and Closure to compile JavaScript, and recently they went as far as creating Dart as a new programming language to replace JavaScript and SPDY as a new protocol to replace HTTP. 
In each of those cases, Google must have decided that they could do better than the current state of the art, but that's not a point I want to discuss here.
The noteworthy point that should be model for other companies is that in each of the cases mentioned, Google also polished their homebrew solutions and published them for everybody else to use. They're not selling it in the sense of asking money for it, but they're selling it in the sense of providing it with at least minimal marketing and minimal support (thru documentation and FAQs) and by opening a feedback channel for outsiders to report bugs or request features. At the same time, they allow outsiders to join the project in several ways. 
An easy but important form of outside help is when outsiders blog about it (that's more marketing, but also basic how-to style tech support) or answer other outsider's questions on the support forums. Those forums are often mostly there for outsiders to help each other, so that the Google employees can save their time to answer just those questions which they themselves find interesting. 
And then, of course, there's the more involved styles of outside-help when people beta-test software, package it into distributions or builds for different architectures, write better documentation (or even books) about it, report bugs and minimize bug test cases. And finally, there's the really involved ways of fixing bugs or contributing features.
With Guava, Chromium, and even Android, Google has started pretty foundational projects, which few companies could imitate. But I think that in almost every project that produces a lot of custom code (that is, builds stuff, instead of buying it), there is at least a fraction of that stuff which could be factored out and given to the world as a little product of its own. If you look at the plethora of Java Modules which are available in the global Maven repository, or all of Ruby's Gems, or Python's Eggs, you can imagine that many of them have been factored out of bigger company-specific projects. Many of those libraries initially started out very small, but with time, they grew to a certain completeness that now makes them The Standard Library™ for their domain. Examples that I have used in my current job include JodaTime, Awaitility, Mockito, and WebDriver.
Besides being a great way to give something small back to the community, I also think that treating your modules as products in their own right can be a great tool to drive separation of concerns. It means putting all the technical and general stuff into the public module and all the company- or project-specific stuff out of the module. This creates a decoupled architecture in which success of your module in the public market place means that you might get features and community-support for free. It even let's you profit in the opposite case: if a better product comes along to fulfill the purpose of your module, your decoupled architecture will allow you to adopt the improved solution. Win-win!
So that's my rule: Buy, don't build. But if you build, also sell.
Thanks for this post go to Schlomo Schapiro for teaching by example with YADT and LML.

Three silver bullets that have been forgotten

I recently thought about what my ideal programming language would be. Just for fun, I googled "ideal programming language" and read the first five hits. Man, was I disappointed! It seems that nobody who has any imagination has ever written about the topic in a way that brings them high up in the Google results. Basically all five authors described their ideal programming language simply by listing features from existing languages!
Here's a ruff list of requirements for the ideal programming language that I came up with:
  • has only a few built-in features so that it con be customized for different domains
  • uses the same core syntax as a basis for all kinds of third-party supplied DSLs 
  • allows much better tool-supported factoring than any current tool for any current language provides
  • allows IDEs to show the code in different views, rearranging methods, even graphical and tabular representations (see also light table and subtext)
  • can scale from being a scripting language for a third-party module up to writing your own DSLs and modules to be used by others
  • allows literate programming, support for verification, and also tests. IDEs should understand the verification annotations (such as preconditions, postconditions, invariants) to point out possible errors and better support refactoring.
  • is explicit. I think that languages with implicit type conversion, implicit defaults, and other automagical things scale badly, because in a larger program, you'll have a mix of implicit and overwritten stuff and need to keep track of when the defaults are used or what else happens "behind the scences". integrating the language with the IDE means that the defaults can be put into new programs and modules by the IDE thus keeping the advantage of quickly starting a project but also gaining the advantage of staying agile by always seeing where everything comes from and being able to change it just right there.
Interestingly, tool support for different views and verification and flexibility to create DSLs all require that the core language has as few features as possible!

Even more interestingly, as I read Fred Brooks famous essay on "no silver bullet" again, I was easily convinced that new programming languages don't actually make that big of a difference in programmer productivity. Basically, there's been nothing really new since Smalltalk and ML! On the other hand, Brooks convincingly argues that the fastest way to write a software is to not write it at all, but to buy it! Or more generally, reuse existing modules! 

While Brook's essay lists a lot of other technologies and methods from which he doesn't expect any significant improvements in productivity, he also mentions three things which actually do have potential in his mind. In short:
  1. Buy, don't build.
  2. Develop incrementally from prototypes.
  3. Find and develop great designers.
Interesting that he mentions incremental development back then in 1986. Agile ain't that new after all! And defining the minimal product hasn't become easier either. It's still one of the essential complexities of software engineering.

Edit: Added "explicitness" in response to Max' comment.

Don’t test your code – test theirs

Nowadays with many technical problems solved by third-party modules we include in our projects, the code we write ourselves is often so simple that unit tests don’t make any sense any more. Of course, we’ll still need automatic system tests (end-to-end tests) and those tests won’t always be green, but when we drill down to find the problem it is most likely that the problem is not in our code, but in our understanding of one of the modules we’re importing!
So how does that pair with “test first”? It simply means that before writing any code depending on third-party modules you explore the third-party APIs by writing unit tests for them which validate your understanding of just those features that you are going to need. And yes, you “test features, not methods”. (The web doesn’t yet know what that means, so you need to find a book such as GOOS to learn about that.)