Tools are not skills

July 29, 2013 by . 16 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

I always find it fairly amazing how many questions appear on Programmers.SE, and Stack Overlow, with the subject of “Which x is better?”. Equally, I’ve been involved in a conversation with co-workers and friends on many occasions where the subject line starts with “What do you think of x?”. The commonality of these two separate threads is that the x is always a language, framework, or tool.

I want to go out on a limb here, and state my conclusion at the start of my essay:

Learning a new tool does not make you a better developer.

Learning a new technique makes you a better developer, tools are just there for convenience.

I’ll start with an example from my own experience. I started off as an ASP.NET WebForms developer straight out of University. I quickly became very knowledgeable about the framework itself, learning how to force it to work for any edge-case I needed, and learning how to build extensions and re-use previous components effectively. I considered myself a talented developer, and was considered to be very highly skilled by my employers. Upon reflection, it is now clear to me that I was a terrible developer.

After a while, the ASP.NET MVC framework was publicly released, to much fanfare. I scoffed, safe in the knowledge that I could make any website faster, and with more functional stability, than any other developer that I knew could develop things in the MVC framework. I began to learn MVC, and being unused to the pattern, struggled to really understand the principles behind how to develop on it. I was a brilliant ASP.NET WebForms developer; I was a terrible developer.

A little while after that, my WebForms project came to an end, and I surveyed the carnage. Bad use of JavaScript was the really key example, because I didn’t understand that putting your JS inside the page and running it as-and-when a control was used was costly and slow. Code reuse in the backend was there, but not ideal, as many actions were done specifically for the page that called them, as opposed to sharing a common data access methodology. The UI code was bloated and ugly. I took this as a good opportunity to start using the MVC framework; clearly it could result in cleaner code, I had seen other coders achieve this for myself. I became an excellent MVC developer. I was still a terrible developer.

Eventually, I came to the realisation that the MVC framework was not ideal. It had some clunky and unwieldy features (such as Microsoft AJAX), and, while it could lead to very clean code, it often did not.[1] It was around this point that I began to learn NUnit, and the principles of TDD; I quickly became a Unit Testing aficionado, and the code I produced jumped up in quality.

At around the same time as learning TDD, I began to investigate the Agile methodologies, and how they could help my development skills. This was the real turning point; I started using my own little Kanban board to manage a project backlog, and watched the quality jump again due to the increased visibility of what I would be building and the increased ability to group tasks with other important tasks. I’d used a technique that I’d never considered to be part of development, as it was neither a tool nor a language, to improve what I was developing. I had learned how something worked, not just how to use something, and it had made my code better.[2]

Since that turning point, I’ve become much more introspective, examining my skills and trying to see if I really understand how something works, not just how to use it. I’ve written my own MVC framework in node.js to prove to myself that I understood not just how to use the MVC pattern, or how to code JavaScript, but that I really understood why the pattern pushes you to better code. In the process, I became intimately familiar with the HTTP spec, and now really understand how the web works, not just how to build things that run on it.

This brings me back to my initial conclusion. It’s clear to me, in retrospect, that I have progressed as a developer not by learning how to use ASP.NET MVC, or how to use jQuery, or how to use node.js, but by delving a little deeper; learning how to apply the MVC pattern in a different language with different principles; learning how the underlying framework of WebForms really interacts with the web browser, not just how to write a custom datepicker control.

It’s very easy to get entranced by a new tool. Perhaps you’re enamoured by the features of a framework, being certain it’ll let you build your apps faster, or more robustly. Or perhaps you’re certain that Silverlight will let you build perfectly acceptable rich client applications without having to learn a new language[3]. I’ve done it myself many times. The trick is to realise that, yes, new frameworks are great, and you should broaden your horizons as much as possible. Just don’t forget that frameworks are transient, and tools become outdated.

We can really see this attitude at work in the recruitment area of the IT industry. Every job advert I’ve seen in the past year has “$language$ developer required”, or “$framework$ developer required” as its title, and contains a list of frameworks and tools that you are expected to have at least 3 years of experience in using[4]. What recruiters and HR managers cannot seem to understand is that each and every framework, tool, and language, has a number of parallels.

Let’s take C# for an example. Yes, C# is very Microsoft-centric, and the .NET framework has a specific set of tools you’re likely to use, NUnit for example. However, at its heart, C# is very similar to Java. Yes, you’re going to declare an anonymous function in a completely different way, and you’re going to use JUnit, as opposed to NUnit, but any C# developer worth his salt should become fully operational in Java in a very short period of time.

On the other hand, your average C# developer may well struggle with Ruby, for example. Dynamic languages and static languages are so different in usage that they require totally different techniques and patterns to use[5]. Dependency Injection? Don’t really need that in a dynamic language. Interfaces? Nah, not like you’re used to.

How do we fix this problem? Well, there are a number of root issues here. The first is developers truly believing that being intimately familiar with, say, rails, makes them a good developer. We fix that by encouraging newer devs to be multi-disciplinary. I firmly believe that the best way to enact change in such a broad area as development is from the bottom; if every new developer comes into the game believing that they need to be familiar with more than just the language, and framework, that’s directly in front of their face all day at work then many of them will go out of their way to learn a broader range of techniques, instead of just learning their framework of choice more intimately, or new a framework every now and again.

The second issue is the issue of organisational change. Most development houses do just one framework, and are very keen to continue to do so. On one hand this makes perfect sense, why change what already works? I recently had a conversation with a developer at another organisation about node.js: he claimed that node.js was perfect for every use case, I assured him that it was not[6]. This attitude of one-size-fits-all is problematic, as developers in small companies aren’t going to be exposed to the broader range of approaches you’ll see in large companies where they recognise that sometimes you want your backend system to be written in a different manner to your API. This is, again, something that needs to come from the bottom. If you’re pushing your own boundaries, discovering new techniques, you’ll begin to learn which are the most appropriate for which scenario. Don’t always punt for the new and shiny, try and keep a level head and really think “do I want to use this tool because it’s the best thing for the job, or because I want to use it”.

The final issue is hiring. This one can only change from the top, so I implore those of you who are in a position to influence the hiring process in your organisation to look at a developer’s skills, not just their résumé[7]. It still surprises me that most development houses either don’t have a development test, or have one that only deals with their core technologies, not the skills that lie behind their use. It would be amazing to see a community resource containing not just a list of “good questions” to ask, but of good skills to look for, and how to look for them effectively.

So, I’ve spoken about how I’ve developed as a programmer not by learning new languages, but by pushing my boundaries in other ways with new management techniques and improving my understanding of the underlying principles of the languages I do know. I hope that a few people who read this can look at their own skills and think “you know, I understand how to use this, but do I understand why?”. Real change is slow and difficult to enact, but in such a young, and social, industry we have an incredible opportunity to make changes as a community.

[1] I have seen developers write five thousand line actions inside a controller, through both laziness and lack of knowledge. Those of you with MVC knowledge should shudder at the thought.

[2] Don’t get me wrong, I’ve not yet hit the pinnacle of my development abilities, I doubt I’m anywhere near (or that I will ever really get there). Everyone has more skills to learn, myself included, and I dedicate a large amount of time to investigation of new things, and practise of the old.

[3] I once had a fairly involved argument with a colleague about whether Silverlight was worth using. I, unfortunately, lost, and the now-legacy Silverlight app has caused a myriad of deployment issues and at least one developer to leave the organisation.

[4] I particularly love ones that are “$cms$ developer required”. Those go straight into my trash.

[5] Yes, C# has the dynamic keyword. No, that doesn’t make it dynamic; dynamic in C# is just a slightly more ducky version of var.

[6] Batch processes was where I finally won that one. Anyone writing enterprise-sized batch processes in node.js has a serious case of myopia, in my opinion.

[7] I recently went to an interview where the only technical question I was asked was “What is the difference between “visibility: hidden” and “display: none” in CSS. This is not an accurate gauge of anything.


Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

Filed under Software Development


Subscribe to comments with RSS.

  • voroninp says:

    Good developer is quite a broad term. If mastering the tool can make someone more performant then it is good to learn this tool.

    Learning a new technique makes you a better developer, tools are just there for convenience.

    I totally agree with you but in many cases tools is the only practical way to adopt a technique. For example AOP and Interception in particular allows you to address cross cutting concerns. Few develoeprs will start implementing its own DI Container or yet another PostSharp. Would it be a sin to aks which container is best concerning this feature and some given context/requirements?

    “Which x is better?” Usually this question is about things from the same domain. Nobody asks whether C# is better than Linux :-). At least I hope it is.

    When people ask about tools they usually want to know about the power of the tool (the amount of convenience) and learning curve. I treat the question “MsTest vs NUnit vs xUnit ?” as absolutely legal.

    Finally, I agree with Simon Brown ( who states that tools selection is a part of architecture. And this selection cannot be done adequately without side-by-side tool comparison.

    To summarise. Let’s not oppose techniques and tools as they both commit to success (or fail if inappropriately applied).

    • Ed Woodcock says:

      I absolutely agree with your final conclusion: You really do need tools as well as skills.

      I guess the point I was trying to make was a bit of a parallel: there are tools and there are techniques, and they are not interchangeable, so let’s make a distinction and stop obsessing about the tools so much to the detriment of the underlying skills!

      I also agree that a starting point for learning a technique definitely tends to be a framework or tool, as that’s a good introduction to the underlying approach. With the example of a DI container, a good approach would be to learn a single choice, and learn it well. Then, move to another choice, and identify the differences, and you’ll start to see the underlying patterns, not just the tools themselves: implementing your own should be left to practice time in order to improve your own skills, or for when you really need an edge-case feature that isn’t provided by another tool 🙂

  • Tools provide structure, and some people don’t know how to respond when that structure is changed or no longer available. It used to be that people started writing programs in a raw language, then moved onto the more abstracted frameworks.

    Nowadays, a lot of people do the reverse. They start out with abstract frameworks, then flip out about how hard it is to write good code in a new (to them) raw language. They become accustomed to having the structure handed to them on a silver platter instead of creating it themselves.

    • Ed Woodcock says:

      Good comment: I have seen this in action at a macro-scale while I was at university. The department started out by teaching Java to first-year students, bringing in the C/C++ in the second year for things that really needed it, like graphics programming. This worked reasonably well (although not brilliantly), as Java was complex enough to teach some skills, but not so hard as to put people off unnecessarily.

      One year the decision was taken to move to teaching the first-year students Python, for the gentler learning curve. These first years progressed to second year, and were met with C++, which is a long jump from Python. Many of them struggled immensely, as the familiarity they had gained with such a high-level language was in no way good preparation for things like pointers and memory management.

      The department changed back to teaching Java the following year.

      Unfortunately, it’s very easy to slip into that approach, even after someone is pushing you to learn new things. I would bet than many developers who are becoming increasingly comfortable with garbage-collected languages would struggle with going back to using malloc and free 🙂 (I certainly would!)

  • Ben Lee says:

    I agree with a lot of what you wrote, but I really don’t think you’ve made a clear distinction between “learning a tool” and “learning a technique”. To me, there isn’t even a clear distinction to be made. Learning to use a tool that embodies a paradigm that is new to you is learning a technique.

    I think it would be a better characterization to say you have to push your boundaries of understanding continuously — constantly learn new techniques, even if some of those techniques are just the ability to use certain tools.

    If you are a new programmer and really pushing yourself to figure out how to use a framework, then you are learning a technique and becoming a better programmer. That doesn’t necessarily make you a “good” programmer (whatever that means) — but your absolute programming ability is less important than the rate at which you are getting better.

    On the other hand, if you are using the same framework you’ve been using for years and just learning it a bit more intimately, or never trying to figure out how it works behind the scenes, or just learning to use a nearly identical framework in another language, then you are mostly stagnating. Anything you do that does not push your limits much is also not going to do a lot to improve your ability.

    • Ed Woodcock says:

      It’s hard to effectively make such a distinction, as you’re right, the two tend to be intrinsically tied together in our minds (which is part of my motivation for writing the article in the first place!). I don’t believe they should be; knowing how to use MVC (a tool) is not as useful as understanding the MVC pattern and being able to apply it properly, regardless of framework or language!

      I do think that programmers who do push their boundaries constantly, even if only to new tools, are going to be very effective programmers. I do believe that your final point mirrors mine closely: there’s no point learning in C#, then spending your time learning, that’s not going to be enough of a difference to improve your skills. However, starting with then moving to Haskell is likely to make a much bigger difference!

  • Hedin says:

    This is exactly what I told to my students. Languages and frameworks evolves quite fast, but the basic principles is much slower. So stuck to principles and evolve with them, instead of followind tools.

  • Ravi says:

    Beautiful article. You have given me a set of guidelines to stick to. Thank you very much

  • Milan Baran says:

    Very nice said! I’m just curious what was the thing that brought you to realize you are a ‘terrible developer’? 😀

    Well, developers most times did not even realize how they can leverage from framework their using by applying proper techniques/patterns. It is sad they are recognized as exports just for that, they spend a lots of time with that framework.

    Actually most sadly thing about this story is when project management or team leaders has lack of overall knowledge. Then your company end up with business ‘tools’ to make development complexity disappear. Actually, it won’t work. It is nice said in following paper, i like it so much 🙂

    A little introduction: Of all the monsters that fill the nightmares of our folklore, none terrify more than werewolves, because they transform unexpectedly from the familiar into horrors. For these, one seeks bullets of silver that can magically lay them to rest. The familiar software project, at least as seen by the nontechnical manager, has something of this character; it is usually innocent and straightforward, but is capable of becoming a monster of missed schedules, blown budgets, and flawed products. So we hear desperate cries for a silver bullet–something to make software costs drop as rapidly as computer hardware costs do.

    • Ed Woodcock says:

      Ha, that’s a good question! I think a good trait to have as a developer is the level of introspection required to look at the code I wrote a year ago and think “oh dear, I really didn’t know what I was doing back then!”. I guess that, over time, when you’re working with your own legacy code there are the odd moments when you really do realise how much you have improved!

      The lack of broad knowledge really is where you end up with those “developer productivity suite”s, which generally just cause all the good developers to become much less productive, but can help out the ones who struggle. Unfortunately, as long as we have the huge divide in skill between our developer gods and our PaulaBeans of the world, there will continue to be a market for such things, as well as managers that buy into them! 🙂

      Overall, I’d really like to see internal training in organisations taken much more seriously, with the professional progress of developers no longer generally dependent on time-served, but on ability. Of course, then we’d have to figure out a way to accurately measure developer ability, and that is unlikely to happen anytime soon! Having read “No Silver Bullet” might be a good starting point, anyway 🙂

  • MAC says:

    I read your whole article, (I’m not a programmer) that’s how good it is! I’m a small business owner in desperate need of guidance from a programmer. I need to know if I wanted to add a page to a Wix HTML 5 platform which would allow visitors to create a personal account, with a profile if possible, a program which would allow lets say, sports fans to pick winners of foot-ball games, calculate wins and losses, automatically update records of players, charge visitors every time they wanted to bet final scores and program would identify and calculate the difference in guessed scores and actual scores, or where visitors could pick the winners of all football teams in a weekly contest of who picks the best, and could calculate buy-ins and payouts. Is this possible and would it take lots of time and money? … Also if there are any programmers who feel they can create something like this, please email me, to infomaceli@gmail.comn

  • Morgan says:

    I believe in this concept from my heart and that is the reason I use notepad/notepad++ for coding. It solves 2 purpose, one it helps me code perfectly and analyse it using my brain, rather than being dependent on IDEs :). Secondly, it is improving my coding skills by not showing compile time error using red lines 😉

    • Yeye says:

      Your article is very heflupl for me.I have a question about playing video in cocos2d.I have a plan to make a painter app which is on the video player.I already made painter app using CCRenderTexture and I successfully player video using MPMoviePlayerController.But MPMoviePlayerController view is always top of all layers, so I can’t draw on the video.Do you know how can i do that?I appreciate your help in advance.

  • Jane E. Millar says:

    I’m no pragrammer by FAR! And I have only Ubuntu/Linux for 2 Days! I Don’t want to go back to Windows 7 Premium! There is Nothing in Windows that I miss!

    Today I was watching a You Tube Video about Ubuntu/Linux VS Windows and My Sound went out, without me doing a thing! If you can contact me and help I would So Much Appreciate it!

    Peace Be unto You All and GOD Bless! Jane.

  • Comments have been closed for this post