Portability without Productivity

I said this was going to be a slow week, so I dug out something I wrote while I was on paternity leave. I was saving it for a rainy day, which is pretty silly since if it was raining I wouldn’t mind staying indoors and writing long posts about levels of abstraction, portability and productivity.


My father and I have a running argument debate about the value of platform independence in the system design and development process. As you might guess, as an employee of a platform company I stand firmly on the “platform neutrality is irrelevant” side of the debate. Having been around Bell Labs during the development of Unix and C as well as having done a stint for an ISV, my father is firmly on the “platform neutrality is important”. Typically, these discussions turn into childish argument where my father continuously says “what if” and I continuously say “that never happens” and neither of us actually makes any ground on convincing the other of the error of their ways.

So herein is yet another salvo in the discussion, for your entertainment. It’s long and drawn out, but since it’s written it means he can’t interrupt me to say “what if” 😄

As mentioned above, my father was at Bell Labs in the early 70′s when Unix and C were developed. I guess it’s no surprise that he harps so much on portability – going back and reading some of the papers that came out of Bell Labs at the time, it’s obvious that their culture heavily valued portability. On Dennis Ritchie’s site (the ‘R’ in ‘K&R’) there is a wide variety of relevant material including The Evolution of the Unix Time-sharing System, The Development of the C Language, and Portability of C Programs and the UNIX System. Given the drastic evolution in computing at the time, it’s not surprising that both Unix and C had portability as primary goals. While I jokingly refer to C’s portability as “write once, compile everywhere”, the reality is that the portability of C and Unix was a key to Unix’s success. According to the portability article, 95% of the C portion of the Unix kernel required no changes when they ported Unix from PDP-11 to the Interdata 8/32. Only the core kernel, which was written in assembly, had to be completely rewritten. Even a significant portion of the device drivers ported over to the new machine.

However, C isn’t just portable. It also provides significant abstraction above assembly code. Anyone who has done any assembly work knows how low level it is and how significant the abstraction jump up to C really is. For example, the simple C statement of “a = b + c” requires three lines of assembly code. Here’s how Ritchie describes C’s level of abstraction:

BCPL, B, and C all fit firmly in the traditional procedural family typified by Fortran and Algol 60. They are particularly oriented towards system programming, are small and compactly described, and are amenable to translation by simple compilers. They are `close to the machine’ in that the abstractions they introduce are readily grounded in the concrete data types and operations supplied by conventional computers, and they rely on library routines for input-output and other interactions with an operating system. With less success, they also use library procedures to specify interesting control constructs such as coroutines and procedure closures. At the same time, their abstractions lie at a sufficiently high level that, with care, portability between machines can be achieved.  (emphasis added) [The Development of the C LanguageDennis M. Ritchie]

That last sentence is key. C’s portability derives from raising the level of abstraction. But raising the level of abstraction also had an important productivity impact. Even if you’re are only building for a single platform and you don’t care about portability, most people would rather code in C rather than assembly because the raised level of abstraction makes the developer much more productive. However, raising the level of abstraction comes with a performance cost. C is pretty ‘close to the machine’ as Richie put it, but there is still a small penalty. If you’re writing ultra-perf sensitive code, sometimes writing in assembly is necessary. There’s a reason why books on the topic keep getting written and the Visual C++ compiler supports inline assembly code.

So here’s my point: Raising the level of abstraction is powerful because it can enable both portability and productivity. However, it also typically carries a performance penalty. As long as the portability and productivity benefits outweigh the performance penalty, everything’s cool. The problem is that productivity is typically WAY WAY WAY more important than portability. So abstractions that enable portability without significant positive productivity benefits will not offset the performance penalty associated with raising the level of abstraction.

The canonical example of “portability without productivity” abstraction that leaps to mind today is the Java platform. Certainly, Java has been pretty successful, though I would argue that its success has been extremely localized. Java on the client has never had mass adoption (the only non-toy Java client app I can think of off the top of my head is Eclipse) and the many of the parts of Java on the server bear a striking resemblance to Microsoft technology. (ODBC vs. JDBC, ASP vs. JSP, Session beans vs. MTS, etc.) Either way, Java adoption has fallen below .NET adoption even though Java had the promise of platform neutrality as well as several years head start. 1

I would argue that one of the main reasons that Java has had only limited success is that while Java is portable, it doesn’t provide much in the way of productivity improvements. Sure, garbage collection is much easier to program to than C++’s explicit memory management model. But Java’s primary competitor (at least in hindsight) was Visual Basic, not C++. While Java focused on portability, VB focused on productivity and in the end it was productivity that drove VB’s massive market share. If you were a Java developer, you had worse tools than VB and worse performance than C++ and the only advantage you had was portability which turned out to be more problematic and less important than advertised. Server apps are rarely re-platformed and Java’s UI implementation caused as many problems as it solved.

From a geek aesthetic perspective, you would have guessed that Java with its clean language and programming model would crush VB and COM in the marketplace, but it just didn’t happen. VB, with its software factory-esque approach, was easier to use and thus attracted more developers who got more apps written. I’d guess that ease of use / developer productivity is the key indicator of success for programming environments. If Java had focused on productivity and portability, I might be working for Sun today.


  1. Obviously, there are varying opinions on this point. SteveB said @ TechEd that .NET is the weapon of choice (my words not his) for 43% of all developers. Java was second with 35% and non .NET Windows development was third (no percentage given).  Even if you want to nit-pick on the numbers, you’d be hard pressed to argue that Java hasn’t been losing ground dramatically to .NET in the past three years since VS 2002 RTMed.

Short Week

After blogging quite a bit last week, I’ve been to busy to blog this week. Between the Labor day holiday Monday and leaving for PDC tomorrow, it’s a short week with lots to do. I’m going to PDC several days early because my family is coming with me and we’re visiting friends and family who still live in LA. Patrick is very excited to be going on a “sky tuka-tuka” i.e. “sky train” i.e. airplane.

Next week will be more of the same from me around here. I’m not going to many sessions – I can get the content on the post conference DVD or simply by emailing the speaker or team directly. PDC is more about hanging out in the community lounge areas the connecting with the other attendees. (Well, that and presenting at the Architecture Symposium.) So I won’t be blogging about cool new technology, but you might see the occasional post about a conversation I had with another attendee. Every time I talk to a customer is an opportunity to learn something and expand my thinking, and PDC represents a great opportunity for lots of conversations.

Two Things I Want From My Digital Camera

GPS and Voice Recording

Omar does a good job covering the GPS front, so I won’t bother repeating those reasons. However, often when I’m taking pictures of something, I want to record a little voice note so I can later remember some details about whatever I’m shooting. Maybe the place has history, or maybe something caught my eye. Often, looking back at picture I can remember those things, but not always.

And since I’m asking, I wouldn’t mind bluetooth so I could shoot pictures of my kids and send them to my parents via my mobile phone. Sure, the phone has a camera…a crappy one. Fun for my MSN Space, but not for any serious picture taking.

Blah Blah Architecture

If you heard my PDC05 Buzzcast but just can’t get enough of my voice, check out Architect MVP Mario Cardinal‘s Blah Blah Architecture podcast. I spent some time with Mario at TechEd talking about the Architecture Resource Center, why we designed it the way we did, why we have a site on MSDN and MS.com, how are taxonomy works, etc. Mario then takes my basic explanation and helps fill in more of the details, such as the relevance of the Architecture Resource Center to folks not using Microsoft technology. We also talked about Architecture Journal as well as why Microsoft invests in architecture.

BTW, I make some of the same points about architecture – as it differs from engineering, that it’s the space between business and technology, and the effect of title inflation – that I’ve made here on this blog this past week.

I guess I need some new material. 😄

Code Smell Question

So as a quick break from all this architecture talk, I’ve got a code smell question. Here’s a scenario, I’m interested in feedback on the best way to solve the issue.

I’m writing some VSTO code for Word using VS05. I want to be able to add and update custom properties on the document. You do this via the CustomDocumentProperties property off the document object. This DocumentProperties collection supports the standard collection type operations such as Add and an indexer. However, it’s a little exception happy. If you attempt to access a property that doesn’t exist, it throws an exception. And if you attempt to add a property that already exists, it throws an exception. So the first time you set a custom property you use the Add method and then after that you use the indexer to access the existing item in the collection and update it’s value.

Of course, the way my code is written, I want to hide this ugliness behind a method so that the rest of my code can simply set custom properties with ease. However, I want to use the same method regardless if the item already exists in the collection. So what’s the best way to implement the method? I can think of two primary ways.

  1. Attempt to access the custom property via the indexer. If it throws an exception, trap it and call Add instead.
  2. Manually iterate through the existing custom properties. If the property exists, update it directly. If it doesn’t, call Add instead.

Neither of these is particularly fragrant from a code smell perspective, but which is less odorous? The first one is more direct to write, but since this is all COM interop code, the COM exception is pretty generic. Theoretically, if something else caused an exception to be thrown, I’d still assume the custom property was just missing and swallow the exception, potentially causing an error somewhere else. However, writing the code to manually iterate through the collection just seems excessive.

In the end, I went with #2 as I was more worried about swallowing exceptions than manual iterating though the collection. What do you think? Was that the right choice?