I have been thinking about productivity lately and have come to wonder about the unintended consequences of intellisense in modern IDEs.
Productivity is efficiently undertaking what you are primarily interested in achieving. The motivation for performing this task is not necessarily relevant. Feeling unproductive leads to frustration that causes positive feedback to being unproductive. It is important, therefore, that we feel we are making progress in our day to day work – identifying tasks, seeing their value and appreciating their completeness are topics for another discussion.
Tools such as intellisense help us achieve small things very quickly and chaining together lots of small things can be productive…or at least feel like its productive. Genuine productivity has two key requirements: experience and knowledge. It is all too easy, unfortunately, for tools to build a straw bridge over any gaps in these two.
Let me be be clear, tools such as intellisense can have a profoundly positive impact on individual productivity. But there is a very real danger that they are relied upon too heavily too early.
When we are writing code we are generally doing one of three things: interacting with out domain model, interacting with libraries and frameworks or producing infrastructure. In each instance experience and knowledge are required so that we know what we are going to do and why we are going to do it. For the purposes of this post I’m going to ignore infrastructure coding as essentially a specific instance of framework interaction.
When we are interacting with our domain model we should be doing so using a DSL distilled from our domain’s ubiquitous language. The ubiquitous language itself is a product of distinct and specific team effort. It should be our lingua franca as we talk about the domain. Some developers will be fluent in the language by virtue of having been involved in the project from the start, others will have been instrumental in establishing the language but new-comers to the project must make a specific effort to learn the domain and it’s language.
Intellisense, combined with the pressures on becoming productive as soon as possible, betrays us here. The constrained list of options displayed following the dot (.) takes away from the developer their responsibility and opportunity to learn the domain and its language in any meaningful sense. With an incomplete knowledge of the domain we are at risk of making changes that are inconsistent with the existing model or repeat aspects already implemented. The net result is that pressure for an individual to become productive leads to a reduction in productivity for the team as a whole.
For framework interaction the problem is different. Intellisense presents us with an arbitrary set of operations against the current object. But which one of those should we choose? Do I want Where().First()? Is this any different from First() with a predicate? Should I loop over Add() or just stuff everything in AddRange()? Will I even think to try AddRange()?
When we are coding the framework it is important that we know what we are doing and what the consequences of our choices are. The seductive power of the next method call following a dot leads to Train Wreck code (cf. Robert Martin’s Clean Code p.98) that violates the Law of Demeter.
In both these cases the problem is exacerbated by pressures on a team and especially its new members to become productive. Tools like intellisense are provided as productivity tools. It seems a no-brainer. But in order to become truly productive we need more knowledge at the edge of our brain than at the end of our fingers. Possibly then we may discover we don’t need quite as many bells and whistles in our IDE as we think we do.