GitHub Copilot – Productivity Boon or Considered Harmful?

We need to talk about GitHub Copilot. This is the ML-driven programming tool – powered by OpenAI Codex – that Microsoft is promoting as “Your AI pair programmer”, and which they claim “works alongside you directly in your editor, suggesting whole lines or entire functions for you.”

Now, full disclaimer: I’ve not been able to try the Copilot Beta yet – there’s a waiting list – so my thoughts are based purely on what I’ve read about it, and what I’ve seen of it in demonstration videos by people who’ve tried.

At first glance, Copilot looks very impressive. You can, for example, just declare a descriptive function or method name, and it will suggest a matching implementation. Or you can write a comment about what you want the code to do, and it will generate it for you.

All the examples I’ve seen were for well-defined, self-contained problems – “calculate a square root”, “find the lowest number” and so on. I’ve yet to see it handle more complex problems like “send an SMS message to this number when a product is running low on stock”.

Copilot was trained on GitHub’s enormous wealth of other people’s code. This in itself is contentious, because when it autosuggests a solution, that might be your code that it’s reproducing without any license. Much has been made of the legality and the ethics of this in the tech press and on social media, so I don’t want to go into that here.

As someone who trains and coaches teams in code craft, though, I have other concerns about Copilot.

My chief concern is this: what Copilot does, to all intents and purposes, is copy and paste code off the Internet. As the developers of Copilot themselves admit:

GitHub Copilot doesn’t actually test the code it suggests, so the code may not even compile or run. 

https://copilot.github.com/

I warn teams constantly that copying and pasting code verbatim off the Internet is like eating food you found in a dumpster. You don’t know what’s in it. You don’t know where it’s been. You don’t know if it’s safe.

When we buy food in a store, or a restaurant, there are rules and regulations. The food, its ingredients, its preparation, its storage, its transportation are all subject to stringent checks to make sure as best we can that it will be safe to eat. In countries where the rules are more relaxed, incidents of food poisoning – including deaths – are much higher.

Code is like food. When we reuse code, we need to know if its safe. The ingredients (the code it reuses), its preparation and its delivery all need to go through stringent checks to make sure that it works. This is why we have a specific package design principle called the Reuse-Release Equivalency Principle – the unit of code reuse is the unit of code release. In other words, we should only reuse code that’s been through a proper, disciplines and predictable release process that includes sufficient testing and no further changes after that.

Maybe that Twinkie you fished out of the dumpster was safe when it left the store. But it’s been in a dumpster, and who knows where else, since then.

So my worry is that prolific use of a tool like Copilot will riddle production software – software that you and I consume – with potentially unsafe code.

My second concern is about understanding and – as a trainer and coach – about learning. I work with developers all the time who rely heavily on copying and pasting to solve problems in their code. Often, they’ll find an example of something in their own code base, and copy and paste it. Or they’ll find an example on the Web and copy and paste that. What I’ve noticed is that the developers who copy and paste a lot tend to pick things up slower – if ever.

I can buy a ready-made cake from Marks & Spencer, but that doesn’t make me a baker. I learn nothing about baking from that experience. No matter how many cakes I buy, I don’t get any better at baking.

Of course, when folk copy and paste code, they may change bits of it to suit their specific need. And that’s essentially what Copilot is doing – it’s not an exact copy of existing code. Well, you can also buy plain cake bases and decorate them yourself. But it still doesn’t make you a baker.

Some will argue “Oh, but Jason, you learned to program by copying code examples.” And they’d be right. But I copied them out of books and out of computing magazines. I had to read the code, and then type it in myself. The code had to go through my brain to get into the software.

Just like the code had to go through Copilot’s neural network to get into its repertoire. There’s perhaps an irony here that what Codex has done is automate the part where programmers learn.

So, my fear is that heavy use of Copilot could result in software that’s riddled with code that doesn’t necessarily work and that nobody on the team really understands. This is a restaurant where most of the food comes from dumpsters.

Putting aside other Copilot features I might take issue with (generating tests from implementation code? – shudder), I really feel that its a brilliant solution to completely the wrong problem. And I’m not the only who thinks this.

If we were to observe developers and measure where their time goes, how much of it is spent looking for code examples? How much of it is spent typing code? That’s a pie chart I’d like to see. What we do know from decades of experience is that developers spend most of their time trying to understand code – often code they wrote themselves. (Hands up. Who else hates Monday mornings?)

Copilot’s main selling point is like trying to optimise a database application that does 10 reads for every 1 write by making the writes faster.

Having the code pasted into your project for you doesn’t reduce this overhead. It’s someone else’s code. You have to read it and you have to understand it (and then, ideally, you have to test it.) It breaks the Reuse-Release Equivalency Principle. It’s not safe reuse.

And Copilot isn’t a safe pair programming partner, being as its only skill is fishing Twinkies out of the code dumpster of GitHub.

I think a lot of more experienced developers – especially those of us who’ve lived through both the promise of general A.I. (still 30 years away, no matter when you ask) and of Computer-Aided Software Engineering – have seen it all before in one form or another. We’re not going to lose any sleep over it.

The tagline for Copilot is “Don’t fly solo”, but anyone using it instead of programming with a real human is most definitely flying solo.

Wake me up when Copilot suggests removing the duplication its creating, instead of generating more of it.

Wax On, Wax Off. There’s Value In Simple Exercises.

One of the risks of learning software development practices using simple, self-contained exercises is that developers might not see the relevance of them to their day-to-day work.

A common complaint is that exercises like the Mars Rover kata or the Fibonacci Number calculator look nothing like “real” code. They’re too simple. There’s no external dependencies. There’s no UI. And so on.

My response to this is that, yes, real code is much more complicated, but if you’re just starting out, you ain’t up to that level of complicated – nowhere near. When students have demanded more complex exercises, the inevitable result is they get stuck and then they get frustrated and they never manage to make much progress. They’re trying to learn to swim in the Atlantic, when what they need is a nice safe shallow pool to get them started in.

So, these simple exercises help students to build their skills and grow their confidence with practices. They also help to build habits. Taking Test-Driven Development as an example, outside of the design thinking that goes on top of the practice, much of it is about habits. Writing a failing test first is a habit. Seeing the test fail before you make it pass is a habit. And so on.

In tackling a simple exercise like the Mars Rover kata, you may apply these habits 20 or more times before you complete the exercise. That repetition reinforces the habits, just like practicing piano scales reinforces muscle memory (as well as building actual muscles, so that you can play faster and more consistently).

As an amateur guitar player, I try to find time every day to repeat some basic exercises. They have nothing to do with real music. But if I don’t do them, I become less capable of playing real music with confidence.

Likewise, as a software developer, I try to find time every day to repeat some basic exercises. Code katas tend to be perfect for this. When it gets more complicated, I can end up bogged down in the complexity – googling APIs, noodling with build scripts, upgrading frameworks and tools (yak shaving, basically). This is also what happens on training courses. As soon as you add, say, React.js, the whole exercise slows to a crawl and the original point of it gets buried under a pile of unshaved yaks.

In music, there are short-form and long-form pieces. To grow as a musician, you do need to expand the scope of the music you play. Not every song can be a 4-bar exercise.

To grow as a software developer, you do need to progress from simple self-contained problems to larger, interconnected systems. But my experience as a developer myself and as a trainer and coach is that it’s a mistake to start with large, complex systems.

It’s also a mistake to think that once you’ve graduated to catching bigger fish, there’s no longer any value in the small ones. Just as it’s a mistake to think that once you’ve learned to play piano concertos, there’s no value in practicing scales any more.

Those habits still need reinforcing, and when I’ve lapsed in daily short-form practice, I find myself getting sloppy on the bigger problems.

Now, here’s the thing: when I teach developers TDD, to begin with they’re focusing on how they’re writing the code far more than what code they’re writing, because that way of working is new to them. They have to remind themselves to write a failing test first. They have to remind themselves to see the test fail. They have to remind themselves to run the tests after every refactoring.

I try to bring them to a point where they don’t need to think about it any more, freeing their minds up to think about requirements and about design. That takes hours and hours of practice, and the need for regular practice never goes away.

Similarly, after thousands of hours of guitar practice, you’ll notice that I don’t even look at what my picking hand is doing most of the time. The pick just hits the right string at the right time to play the note I want to play, even when I’m playing fast.

It’s the same with practices like TDD and refactoring. As long as I maintain those good habits, I don’t have to consciously remind myself to apply them on real code – it just happens. And the end result is code that’s more reliable, simpler, modular, and much easier to change.

So you may be thinking “What has this simple exercise got to do with real software?”. But they do have a serious purpose and they do help build and maintain fundamental habits, freeing our minds to focus on the things that matter.

As Mr. Miyagi in Karate Kid says, ‘Wax On, Wax Off’.

Code Craft – The Proof of the Pudding

In extended code craft training, I work with pairs on a multi-session exercise called “Jason’s Guitar Shack”. They envision and implement a simple solution to solve a stock control problem for a fictional musical instrument store, applying code craft disciplines like Specification By Example, TDD and refactoring as they do it.

The most satisfying part for me is that, at the end, there’s a demonstrable pay-off – a moment where we review what they’ve created and see how the code is simple, readable, low in duplication and highly modular, and how it’s all covered by a suite of good – as in, good at catching it when we break the code – and fast-running automated tests.

We don’t explicitly set out to achieve these things. They’re something of a self-fulfilling prophecy because of the way we worked.

Of course all the code is covered by automated tests: we wrote the tests first, and we didn’t write any code that wasn’t required to pass a failing test.

Of course the code is simple: we did the simplest things to pass our failing tests.

Of course the code is easy to understand: we invested time establishing a shared language working directly with our “customer” that subconsciously influenced the names we chose in our code, and we refactored whenever code needed explaining.

Of course the code is low in duplication: we made a point of refactoring to remove duplication when it made sense.

Of course the code is modular: we implemented it from the outside in, solving one problem at a time and stubbing and mocking the interfaces of other modules that solved sub-problems – so all our modules do one job, hide their internal workings from clients – because to begin with, there were no internal workings – and they’re swappable by dependency injection. Also, their interfaces were designed from the client’s point of view, because we stubbed and mocked them first so we could test the clients.

Of course our tests fail when the code is broken: we specifically made sure they failed when the result was wrong before we made them pass.

Of course most of our tests run fast: we stubbed and mocked external dependencies like web services as part of our outside-in TDD design process.

All of this leads up to our end goal: the ability to deploy new iterations of the software as rapidly as we need to, for as long as we need to.

With their code in version control, built and tested and potentially deployed automatically when they push their changes to the trunk branch, that process ends up being virtually frictionless.

Each of these pay-offs is established in the final few sessions.

First, after we’ve test-driven all the modules in our core logic and the integration code behind that, we write a single full integration test – wiring all the pieces together. Pairs are often surprised – having never tested them together – that it works first time. I’m not surprised. We test-drove the pieces of the jigsaw from the outside in, explicitly defining their contracts before implementing them. So – hey presto – all the pieces fit.

Then we do code reviews to check if the solution is readable, low in duplication, as simple as we could make it, and that the code is modular. Again, I’m not surprised when we find that the code ticks these boxes, even though we didn’t mindfully set out to do so.

Then we measure the code coverage of the tests – 100% or very near. Again, I’m not surprised, even though that was never the goal. But just because 100% of our code is covered by tests, does that mean it’s really being tested. So we perform mutation testing on the code. Again, the coverage is very high. These are test suites that should give us confidence that the code really works.

The final test is to measure the cycle time from completing a change to seeing it production. How long does it take to test, commit, push, build & re-test and then deploy changes into the target environment? The answer is minutes. For developers whose experience of this process is that it can take hours, days or even weeks to get code into production, this is a revelation.

It’s also kind of the whole point. Code craft enables rapid and sustained innovation on software and systems (and the business models that rely on them).

Now, I can tell you this in a 3-day intensive training course. But the extended training – where I work with pairs in weekly sessions over 10-12 weeks – is where you actually get to see it for yourself.

If you’d like to talk about extended code craft training for your team, drop me a line.

What Is ‘Leadership’ Anyway?

If you spend any time on LinkedIn you’re likely to bump into content about this thing called “leadership”. Many posters fancy themselves as experts in this mysterious quality. Many promote themselves as professional “leaders”.

I’m sure you won’t be surprised to learn that I think this is nonsense. And now I’m going to tell you why.

Leading Is Not What You Think It Is?

Let’s think of what that word means: “Lead the way”, “Follow my lead”, “Tonight’s leading news story”, “Mo Farah is in the lead”.

When you lead, it usually means that you go first.

Leading is distinctly different from commanding or inspiring, but that’s what many professional “leaders” mistake it for.

Leaders don’t tell people where to go. They show people the way by going first.

I don’t tell people to write their tests first. I write my tests first and show them how. I lead by example.

‘Leader’ Is Not A Job Title

Organisations appoint what they believe to be good leaders into roles where leading by example is difficult, if not impossible. They give them titles like “Head of” and “Director of” and “Chief” and then promote them away from any activity where they would have the time to show rather than tell.

The real leaders are still on the shop floor. It’s the only place they can lead from.

And, as we’ve probably all experienced, promoting the people who could set the best example into roles where they can’t show instead of tell is a very common anti-pattern.

We Are Not Your Flock

Another common mistake is to see leadership as some kind of pastoral care. Now, I’m not going to suggest that organisations shouldn’t take an interest in the welfare of their people. Not just because happy workers make better workers, but because they are people, and therefore it’s the right thing to do.

And executives could set examples – like work-life balance, like the way they treat people at all levels of the corporate ladder, and like how much they pay people (yeah, I’m looking at you, gig economy) – but that’s different to the way many of them perceive that role.

Often, they’re more like religious leaders, espousing principles for their followers to live by, while indulging in drug-fuelled orgies and embezzling the church’s coffers.

And the care that most people need at work is simply to not make their lives worse. If you let them, grown-ups will grown-up. They can buy their own massage chair if they want one. Nothing more disheartening than watching managers impose their ideas about well-being on to actual adults who are allowed to drink and drive and vote.

If people are having problems, and need help and understanding, then be there for that. Don’t make me go to paintball. I don’t need it, thanks.

The Big Bucks

Most developers I know who moved into those “leadership” roles knew it was a mistake at the time – for the organisation and for themselves – but they took the promotion anyway. Because “leadership” is where the big bucks are.

The average UK salary for a CTO is £85,000. For a senior developer, it’s £60,000 (source: itjobswatch.co.uk). But how senior is “senior”? I’m quite a senior developer. Most CTOs are junior by comparison.

And in most cases, CTO is a strategic command – not a leadership – role (something I freely admit I suck at). A CTO cannot lead in the way I can, because I set an example for a living. For all I know, there are teams out there I’ve never even met who’ve been influenced more by me than by their CTO.

‘Leader’ Is A Relative Term

When I’ve been put in charge of development teams, I make a point of not asking developers to do anything I’m not prepared to at least try myself, and this means I’m having to learn new things all the time. Often I’m out of my comfort zone, and in those instances I need leadership. I need someone to show me the way.

Leadership is a relationship, not a role. It’s relative. When I follow you, and do as you do, then you are the leader. When you do as I do, I’m the leader.

In the course of our working day, we may lead, and we may follow. When we’re inexperienced, we may follow more than we lead. But every time you’ve shown someone how you do something and they’ve started to do it too, you’re a leader.

Yes, I know. That sounds like teaching. Funny, that.

But it doesn’t have to be an explicit teacher-student relationship. Every time you read someone’s code and think “Oh, that’s cool. I’m going to try that”, you have been led.

It’s lonely at the top

For sure, there are many ways a CxO could lead by example – by working reasonable hours, by not answering emails or taking calls on holidays, by putting their trust in their people, or by treating everyone with respect. That’s a rare (and beautiful) thing. But it’s the nature of heirarchies that those kinds of people tend not to get ahead. And it’s very difficult to lead by example from a higher strata. If a CTO leaves the office at 5:30pm, but none of her 5,000 employees actually sees it, does it make a sound?

Show, Don’t Tell

So, leadership is a very distinct thing from command. When you tell someone to do something, you’re commanding. When you show them how you do it – when you go first – that’s leading.

“Show, don’t tell” would be – if it had one – Codemanship’s mission statement. Right from the start, I’ve made a point of demonstrating – and not presenting – ideas. The PowerPoint content of Codemanship training courses has diminished to the point of almost non-existent over the last 12 years.

And in that sense, I started Codemanship to provide a kind of leadership: the kind a CTO or VP of Engineering can’t.

Set Your Leaders Free

I come across so many organisations who lack technical leadership. Usually this happens because of the first mistake – the original sin, if you like – of promoting the people who could be setting a good example into roles where they no longer can, and then compounding that mistake by stripping authority and autonomy from people below that pay grade – because “Well, that’s leadership taken care of”.

I provide a surrogate technical leadership service that shouldn’t need to exist. I’m the CTO who never took that promotion and has time – and up-to-date skills – to show you how to refactor a switch statement. I know people who market themselves as an “Interim CTO”. Well, I’m the Interim Old Programmer Who’s Been Around Forever.

I set myself free by taking an alternative career path – starting my own company. I provide the workshops and the brown bag sessions and the mobbing sessions and the screencasts and the blog posts that you could be creating and sharing within your organisation, if only they’d let you.

If only they’d trust you: trust you to manage your own time and organise things the way you think will work best – not just for getting things done, but for learning how to do them better.

People working in silos, keeping their heads down, is antithetical to effective leadership. Good ideas tend to stay in their silos. And my long experience has taught me that broadcasting these ideas from on-high simply changes nothing.

Oh, The Irony

I believe this is a pretty fundamental dysfunction in organisational life. We don’t just have this problem in tech: we see it repeated in pretty much every industry.

Is there a cure? I believe so, and I’ve seen and been involved with companies who’ve managed to open up the idea of leadership and give their people the trust and the autonomy (and the resources) to eventually provide their own internal technical leadership that is self-sustaining.

But they are – if I’m being honest – in the minority. Training and mentoring from someone like me is more likely to lead to your newly inspired, more highly skilled people moving on to a company where they do get trust and autonomy.

This is why I warn clients that “If you water the plant, eventually it’ll need a bigger pot”. And if pushed to describe what I do, I tell them “I train developers for their next job”. Would that it were not so, but I have no control over that.

Because I’m not in charge.

Training Is Expensive. But Not As Expensive As Not Training.

However they choose to learn – from books, videos, blogs, online courses, instructor-led training, etc – by far the biggest cost in building a developer’s skills is the time that it takes.

I’ve worked with several thousand developers in more than 100 organisations over the last decade, so I have a perspective on how much time is really required. If you’re a manager, you may want to sit down for this.

Let’s start from scratch – a newly-minted programmer, just starting out in their dev career. They may have been programming for 6-12 months, perhaps at school or in a code club, or at home with a couple of books.

At this point, they’re a long way from being competent enough to be left alone to get on with writing real software for real end users in a real business. Typically, we find that it takes another 2-3 years. Before then, they’re going to need a lot of supervision – almost continuous – from a more experienced developer.

Of course, you could just leave them to their own devices, freeing up that more productive mentor to write their own code. But we know that the cost of maintaining code over its lifetime is an order of magnitude higher than the cost of writing it in the first place. An inexperienced developer’s code is likely to be far less maintainable, and therefore cost far more to live with.

This is the first hidden cost of learning, and it’s a big one.

But it’s not just about maintainability of code, of course. Inexperienced developers are less likely to know how to pin down requirements, and therefore more likely to build the wrong things, requiring larger amounts of rework. And this is rework of code that’s harder to change, so it’s expensive rework.

More mature organisations recognise this, and invest more to get their developers up to speed sooner. (Many developers, sadly, never learn to write maintainable code at any point in their career – it’s pot luck if you happen to end up being exposed to good practices).

Or you could exclusively hire more experienced developers, of course. But that plan has two fatal flaws. Firstly, hiring developers is very expensive and takes months. Secondly, if nobody hires inexperienced developers, where will these experienced developers come from?

So, you end up paying the piper one way or another. You can pay him for training. Or you can pay him for constant supervision. Or you can pay him for bug fixes and rework. Or you can pay him to try and recruit senior developers.

It turns out that training – I mean, really training – your developers is the cheapest option. It’s also the option least chosen.

On paper, it sounds like a huge investment. Some development organisations spend as much as 25% of their entire budget on learning and improving. Most organisations balk at this. It’s too much!

The lion’s share of this manifests in the developers’ time. They might, for example, give developers one day a week dedicated to learning and improving (and, as they become more senior, researching and experimenting). For a team of 6 developers, that adds up to £140,000 a year of developer time.

They might send teams on training courses. A group of 12 – the average Codemanship class size – on a 3-day course represents approximately £16,000 of dev time here in London.

These are some pretty big numbers. But only when you consider them without the context of the total you’re spending on development, and more importantly, the return your organisation gets from that total investment.

I often see organisations – of all sizes and shapes – brought to their knees by legacy products and systems, and their inability to change them, and therefore to change the way they do business.

Think not about the 25%. Think instead about what you’re getting from the other 75%.

I’m A Slacker, And Proud Of It

That probably sounds like an unwise thing to put on your CV, but it’s nevertheless true. I deliberately leave slack in my schedule. I aim not to be busy. And that’s why I get more done.

As counterintuitive as it sounds, that’s the truth. The less I fill my diary, the more I’m able to achieve.

Here’s why.

Flash back to the 1990s, and picture a young and relatively inexperienced lead software developer. Thanks to years of social conditioning from family, from school, from industry, and from the media, I completely drank the Hussle Kool-Aid.

Get up early. Work, work, work. Meetings, meetings, meetings. Hussle, hussle, hussle. That’s how you get things done.

I filled my long work days completely, and then went home and read and practiced and learned and answered emails and planned for next work-packed day.

A friend and mentor recognised the signs. He recommended a I read a book called Slack: Getting Past Burnout, Busywork & The Myth of Total Efficiency by Tom DeMarco. It changed my life.

Around this time, ‘Extreme Programming’ was beginning to buzz on the message boards and around the halls of developer conferences. These two revelations came at roughly the same time. It’s not about how fast you can go in one direction – following a plan. It’s about how easily you can change direction, change the plan. And for change to be easy, you need adaptive capacity – otherwise known as slack.

Here was me as a leader:

“Jason, we need to talk about this urgent thing”

“I can fit you in a week on Thursday”

“Jason, should we look into these things called ‘web services’?”

“No time, sorry”

“Jason, your trousers are on fire”

“Send me a memo and I’ll schedule some time to look into that”

At an organisational level, lack of adaptive capacity can be fatal. The more streamlined and efficient they are at what they currently do, the less able they are to learn to do something else. Try turning a car at its absolute top speed.

At a personal level, the drive to be ever more efficient – to go ever faster – also has serious consequences. Aside from the very real risk of burning out – which ends careers and sometimes lives – it’s actually the dumbest way of getting things done. There are very few jobs left where everything’s known at the start, where nothing changes, and where just sticking to a plan will guarantee a successful outcome. Most outcomes are more complex than that. We need to learn our way towards them, adjusting as we go. And changing direction requires spare capacity: time to review, time to reflect, time to learn, time to adjust.

On a more serious note, highly efficient systems tend to be very brittle. Think of our rail networks. The more we seek to make them more efficient, the bigger the impact on the network when something goes wrong. If we have a service that takes 30 minutes to get from, say, London Waterloo to Surbiton, and we run it every hour, if there’s a delay, there’s 30 minutes of slack to recover in. The next train doesn’t have to be late. If we run it every 30 minutes – at maximum “efficiency” – there’s no wiggle room. The next train will be late, and the one after that, etc.

My days were kind of like that; if my 9am meeting overran, then I’d be late for my 9:20, and late for my 10am, and so on.

When we stretch ourselves and our systems to breaking point – which is what ‘100% efficiency’ really means – we end up being rigid (hard to change) and brittle (easy to break).

We’re seeing that now in many countries’ handling of the pandemic. After a decade of ideological austerity stripping away more and more resources from public services in the UK, forcing them to become ever more ‘efficient’, the appearance of the unexpected – though we really should have been expecting it at some point – has now broken many of those services, and millions of lives.

Since the late 90s, I’ve deliberately kept my diary loose. For example, I try very hard to avoid running two training courses in the same week. When someone else was managing my diary and my travel arrangements, they’d have me finishing work in one city and jumping on a late train or flight to the next city for another appointment the next morning. This went wrong very, very often. And there was no time to adjust at all. If you’ve ever tried to find a replacement laptop at 7am in a strange city, you’ll know what I’m talking about.

So I highly recommend reading Tom’s book, especially if you’re recognising the symptoms. And then you too can become a more productive slacker.

Codemanship Code Craft Videos

Over the last 6 months, I’ve been recording hands-on tutorials about code craft – TDD, design principles, refactoring, CI/CD and more – for the Codemanship YouTube channel.

I’ve recorded the same tutorials in JavaScript, Java, C# and (still being finished) Python.

As well as serving as a back-up for the Codemanship Code Craft training course, these series of videos forms possibly the most comprehensive free learning resource on the practices of code craft available anywhere.

Each series has over 9 hours of video, plus links to example code and other useful resources.

Codemanship Code Craft videos currently available

I’ve heard from individual developers and teams who’ve been using these videos as the basis for their practice road map. What seems to work best is to watch a video, and then straight away try out the ideas on a practical example (e.g., a TDD kata or a small project) to see how they can work on real code.

In the next few weeks, I’ll be announcing Codemanship Code Craft Study Groups, which will bring groups of like-minded learners together online once a week to watch the videos and pair program on carefully designed exercises with coaching from myself.

This will be an alternative way of receiving our popular training, but with more time dedicated to hands-on practice and coaching, and more time between lessons for the ideas to sink in. It should also be significantly less disruptive than taking a whole team out for 3 days for a regular training course, and significantly less exhausting than 3 full days of Zoom meetings! Plus the price per person will be the same as the regular Code Craft course.

Proactive vs Reactive Learning (or “Why Your Company Only Does Easy Things”)

Imagine you lead an orchestra. The word comes down from on high “Tonight, our audience demands you play Rachmaninoff’s Piano Concerto No. 3. The future of the orchestra depends on it. We’re all counting on you.”

But your orchestra has no pianist. Nobody in your orchestra has even touched a piano, let alone taken lessons. You turn to the lead violin: “Quick. Google ‘how to play piano?’ “

Now, of course, there’s absolutely no chance that any human being could learn to play piano to that standard in a day. Or a week. Or a month. It takes a lot of time and a lot of work to get to that level. Years.

The inevitable result is that the orchestra will not be playing Rachmaninoff’s Piano Concerto No. 3 that evening. At least, not with the piano part. And that’s kind of essential to a piano concerto.

I see tech organisations in this situation on a regular basis. They discover a need that they’re simply nowhere near competent enough to deal with – something completely beyond the range of their current capabilities. “The users demand that the software learns from their interactions and anticipates their needs. Quick. Google ‘how to train a machine?'” “The customer demands a custom query language. Quick. Google ‘how to write a compiler?'” And so on.

Have we become so used to looking stuff up on Stack Overflow, I wonder, that we’ve forgotten that some of this stuff is hard? Some of these things take a long time to learn? Not everything is as easy as finding out what that error message means, or how to install a testing framework using NPM?

The latter style of learning is what some people call reactive. “I need to know this thing now, because it is currently impeding my progress.” And software development involves a lot of reactive learning. You do need to be rather good at looking stuff up to get through the typical working day, because there are just so, so many little details to remember.

Here’s the thing, though: reactive learning only really works for little details – things that are easy to understand and can be learned quickly. If the thing that impedes our progress is that we require a road bridge to be built to get us over that canyon, then that’s where we see the limits of reactive learning. It can remove small obstacles. Big problems that takes a long time to solve require a different style of learning that’s much more proactive.

If your orchestra only plays the instruments needed for the exact pieces they’ve played up to that point, then there’s in increased likelihood that there’ll be gaps. If a dev team only has the exact skill set for the work they’ve done up to that point, there are likewise very likely to be gaps.

It’s hard, of course, to anticipate every possible future need and prepare months or years in advance for every eventuality. But some orgs have a greater adaptive capacity than others because their people are skilled beyond today’s specific requirements. That is to say, they’re better at solving problems because they have more ways of solving problems – more strings to their bow (or more keys to their piano, if you like).

Compiler design might sound like the kind of esoteric computer-sciency thing that’s unlikely to arise as a business need. But think of it this way: what’s our code built on? Is the structure of programs not the domain model we work in every day? While I’ve never designed a compiler, I have had numerous occasions when – to write a tool that makes my job easier – it’s been very useful to understand that model. Programmers who understand what programs are made of tend to be more effective at reasoning about code, and better at writing code that’s about code. We use those tools every day, but all tooling has gaps. I’ve yet to meet a static analysis tool, for example, that had all the rules I’d be interested in applying to code quality.

The most effective dev teams I’ve come into contact with have invested in custom tooling to automate repetitive donkey work at the code face. Some of them end up being open-sourced, and you may be using them yourself today. How did you think our test runner’s unit test discovery worked?

Some books about stuff I had no immediate need to know but read anyway

Now, we could of course hire a pianist for our orchestra – one who already knows Rachmaninoff’s Piano Concerto No. 3. But guess what? It turns out pianists of that calibre are really difficult to find – probably because it takes years and years to get to that standard. (No shortage of people who manage pianists, of course.) And now you remember how you voted against all those “superfluous” music education programmes. If only you could have known that one day you might need a concert pianist. If only someone had warned you!

Well, here I am – warning you. Not all problems are easy. Some things take a long time to learn, and those things may crop up. And while nobody can guarantee that they will, this is essentially a numbers game. What are the odds that we have the capability – or can buy in the capability at short notice (which opens the lid on a can of worms I call “proactive recruitment”) – to solve this problem?

Most of the time, organisations end up walking away from the hard problems. They are restricted to the things most programmers can solve. This is not a good way to build competitive advantage, any more than sticking to works that don’t have a piano part is a good way to run a successful orchestra.

Enlightened organisations actively invest in developing capabilities they don’t see any immediate need for. Yes, they’re speculating. And speculation can be wasteful. Just like all uncertain endeavors can be wasteful. But there are usually signposts in our industry about what might be coming a year from now, a decade from now, and beyond.

And there are trends – the continued increase in available computing power is one good example. Look at what would be really useful but is currently computationally too expensive right now. In 1995, we saw continuous build and tests cycles as highly desirable. But most teams still ran them overnight, because the hardware was about 1000 times slower than today. Now coming into vogue – as I predicted it would over a decade ago – more and more of us are building and testing (and even automatically inspecting) our code continuously in the background as we type it. That was totally foreseeable. As is the rise of Continuous Inspection as a more mainstream discipline off the back of it.

There are countless examples of long-established and hugely success businesses being caught with their pants down by Moore’s Law.

Although digital photography was by no means a new invention, its sudden commercial viability 20 years ago over chemical photography nearly finished Kodak overnight. They had not speculated. They had not invested in digital photography capability. They’d been too busy being the market leader in film.

And then there was the meteoric rise of guitar amp simulators – a technology long sneered at (but begrudgingly used) by serious players, and less serious players like myself. The early generations of virtual amps didn’t sound great, and didn’t feel like playing through a real amp with real tubes. (Gotta love them tubes!) But – damn – they were convenient.

The nut they couldn’t crack was making it sound like it was being recorded through a real speaker cabinet with a real microphone. There was a potential solution – convolution, a mathematical process that can combine two signals, so the raw output of a guitar amp (real or virtual) can be combined with an “impulse response” (a short audio sample, like the short reverberation in a room after you click your fingers) of a cabinet and microphone to give a strikingly convincing approximation of what that signal would sound like in the space – or what that guitar amp output would sound like through those speakers recorded with that microphone. Now, suddenly, virtual guitar amps were convenient and sounded good.

But up to that point, convolution had been too computationally expensive to be viable for playing and recording on commercially available hardware. And then, suddenly, it wasn’t. Queue mad dash by established amp manufacturers to catch up. And, to be fair to them, their virtual amp offerings are pretty spiffy these days. Was this on their radar, I wonder? Did the managers and the engineers see virtual amp technology looming on the horizon and proactively invest in developing that capability in exactly the way Kodak didn’t? Not before virtual amp leaders like Line 6 had taken a chunk of their market share, I suspect. And now convolution is everywhere. So many choices, so many market players old and new.

You see, it’s all well and good making hay while the sun shines. But when the weather turns, don’t end up being the ones who didn’t think to invest in a umbrella.

Introduction to Test-Driven Development Video Series

Over the last month, I’ve been recording screen casts introducing folks to the key ideas in TDD.

Each series covers 6 topics over 7 videos, with practical demonstrations instead of slides – just the way I like it.

They’re available in the four most used programming languages today:

Of course, like riding a bike, you won’t master TDD just by watching videos. You can only learn TDD by doing it.

On our 2-day TDD training workshop, you’ll get practical, hands-on experience applying these ideas with real-time guidance from me.

Scheduled Online TDD Courses, May – July

I’ve got three publicly scheduled 2-day Test-Driven Development courses coming up:

I appreciate that we’re all going through some – how shall we say? – interesting times right now, and that many of you are getting used to working remotely for the first time.

Hopefully what you’re learning is that distributed teams can be as effective – sometimes even more effective – than co-located teams.

For every advantage of co-location lost, we gain another advantage when we remove the distractions of open plan offices, of long life-sapping commutes, and of never-ending meetings because we just happen to be in the same building,

And online training can be just as effective – sometimes even more effective – than onsite training. We are, after all, looking at and working on code. Screen sharing and webcams work just as well as sitting next to each other once you get the hang of it.

It’s pretty much the exact same training I do in person, only you can enjoy it from the comfort of your own home, without the daily commute either side and without the many distractions of being on your office. And the catering can be great – depending on what you’ve got in your fridge.

To find out more about the course, visit http://codemanship.co.uk/tdd.html