This post is, belatedly, inspired by the Ministry of Testing blog idea: The Struggle with Learning to Code. I have a Computer Science degree, and have been programming for a while. (I started doing it as a hobby, and then studied it, and then got paid to do it.) I struggle with learning to code, and have for a while.
Given my background, why do I struggle? The simple answer is that there’s so much to learn. What’s worse, my To Learn list gets bigger over time – new things are added to it more quickly than I can learn things off it.
I started coding in BASIC, and then Z80 machine code. After I graduated, my first job was writing C. As a result, I was comfortable with procedural programming. Switching to Object Oriented was a struggle, and took quite a while. I had been taught OO at university, but it wasn’t in my mental muscle memory and instead took conscious thought over quite a while. Signs of someone still making this transition from procedural to OO are things like God classes, very long methods, anaemic models and so on.
Another big division is functional programming, because it changes how you think about encapsulation, state, loops, breaking work down (things like currying functions) and so on.
Recently I’ve dabbled in quantum computing, which is different again. Code becomes probabilistic rather than deterministic. The world is divided into two regions – the region of classical computing where you work with data, and the region of quantum computing where you work with meta-data (probabilities associated with states rather than with the states themselves) to preserve the superposition of states.
I would add set-based programming as a final big division. I don’t think this is a commonly-used term, but it’s for things like SQL and R, and also LINQ in C#. If you have 17 (or 17,000,000) rows in a database table that need updating, you can do it as you’d expect to in a procedural program – individually looping through each one. In SQL this would probably be with a cursor, and is sometimes described as RBAR – row by agonising row. But it would be less code and much faster to issue one update statement with the correct where clause, and let the database work out how to translate that (via an execution plan) into updating individual rows.
These major divisions – procedural, OO, functional, quantum and set-based – force you to learn new ways of thinking about problems and how you solve them. If you focus on the surface differences (things like syntax and names of things) and ignore the underlying differences, then you end up e.g. writing OO code that’s effectively procedural code that’s had a tiny amount of OO fairy dust sprinkled over it. It will be less efficient, harder to understand and change, and have other problems that you would avoid if you worked with the grain of the material you’re using.
Domain specific differences
There are other differences within these major divisions. For instance, asynchronous programming can take some getting used to. This might crop up using AJAX in a website, or async / await in some back-end C#. You are no longer in full control of what happens when, and have to cope with things happening in unexpected or unhelpful orders. There isn’t a single unbroken flow of execution – instead the flow gets chopped up into smaller bits, which might be assembled in a few different orders. Debugging and logging what happens in production become harder.
Then there are loads of other differences, based on either what’s important, or what’s available or not. A by no means exhaustive list is: latency, throughput, memory efficiency, distributed database transactions / sagas.
Finally, there’s the details of the specific problem you’re trying to solve for users. This is an even bigger list, so I won’t bother trying to go into details.
There’s some good news in this blizzard of new, as there are some skills that I have discovered are transferrable across these divisions. These are things like being able to break a problem down into pieces that are small enough to solve, naming things well, how and when to use comments, testing, debugging and so on.
I struggle with learning to code, because the learning never stops. On the one hand this is daunting and can be demoralising. On the other hand, it means that there’s always something new to explore, a new way of solving problems and a new way of expressing myself in code. Along the way, there are general skills to pick up that seem to stay useful in new situations.