Why Learning Programming is Slow

Computers can only do what you tell them to do.
By Ciprian Stratulat • Updated on May 2, 2023
blog image

Is programming harder than other skills out there? It's honestly hard to say for certain. However, I do think that programming is less forgiving than other skills for beginners because of the limitations that current computers have. What I mean is that there is no room for error in your thinking as a software developer, because computers are fairly dumb and they cannot infer what you meant to do. They only do exactly what you tell them to do.

 

The instructions you provide to the computer when you write a program are still fairly low level in this day and age: you can't instruct a computer to build you a website, for example. You have to tell it exactly how to build a website, step-by-step in great detail, using only the limited set of instructions that are available in the programming language you are using. Skip one step, or get one step slightly wrong, and your program won't work. Or worse, it will work in most cases, and then mysteriously fail in some obscure cases.

programming workflow diagram

Image Source: Programming Workflow, Freecodecamp.org

On the positive side, things have gotten a bit easier over time and, in general, there is a trend towards higher-level thinking and, in some cases, computer-assisted software development. In addition, free, open-source libraries and modules that package certain "abilities" and make them easy to use in your own software are making it easier to build ever more complicated programs.

Going back to the website building example, things have gotten much easier over the last couple of decades. This is not because computers have become smarter and are able to understand more of our intentions, but simply because people have created and offered for free these packages of higher-level abilities that make it easier to build a website.

Despite all this, however, programming itself is still very much about the low-level details rather than the high-level picture, although awareness of the latter is always something that a good software developers keeps in mind. So with all this in mind, let's explore a few different reasons why learning programming is a slow process.

 

 

Why Programming Means Thinking in Small Steps

Contrary to what beginners may think, what most people learning to code struggle with is not as much the new syntax of a programming language, or even the programming environment with all its tools and commands. From my experience, the hardest thing about programming is that it requires a slightly different way of thinking.

As humans, we are pretty good at doing complex tasks, but are not always good at describing how we achieve what we do. Sometimes, that's because humans genuinely don't know how we perform those tasks. For example, I couldn't exactly explain how I recognize shapes, or how I am able to utter words.

Some tasks, however, you can describe in great detail, but you're not in the habit of doing so. If I asked you to describe your morning routine, you could do it. You could probably describe every step in great detail, but you don't think about the details of your daily routine this often, so it would require some thinking. Programming requires thinking in very small steps, using a limited number of building blocks and concepts to build solutions to general problems. This is because, on some level, programming is simply the act of translating your intentions into a language that computers can understand.

As I mentioned earlier, despite their ever-expanding raw computational powers, computers are still fairly dumb: naturally, they only understand a few, low-level concepts. Popular programming languages build on top of those abilities and offer slightly-higher level concepts to work with, but even these concepts, or building blocks, are still more like Lego pieces rather than finished parts.

Let's go over an example: say I give you a list of names - 'Mary,' 'Alice,' 'James' - and I ask you what number you'll get if you put together the number of letters in each of the names. After some thinking, you could probably tell me that the number is 455. This is because Mary has 4 letters, Alice has 5 letters and James has 5 letters. This is a question that a computer can also answer, and in fact it would answer it in a somewhat similar fashion to humans. Namely by taking each name in turn, counting the letters in each name, keeping track of those counts, and finally building the number 455.

But the solution that I described here is actually pretty high level. What does it mean to take each name in turn? How do you actually determine the number of letters in each word? How do you keep track of the counts for each word? How do you actually assemble the final number? These are pretty high-level tasks that computers would not naturally know how to perform. A program needs to be written that breaks down each and every step into smaller steps that a computer can actually understand.

A more detailed solution could probably be something like this:

 

  • Store in memory the list of names ('Mary,' 'Alice,' 'James')
  • Store in memory the fact that you are now considering the first name in that list
  • Recover from memory what the first name in the list is ('Mary')
  • Store a counter in memory (starting at 0)
  • Go letter-by-letter through the current name, increasing this counter by 1 for each letter, until you run out of letters
  • Store the final counter in memory (4)
  • Store in memory the fact that you are now considering the second name in the list of names
  • Recover from memory what this second name is ('Alice')
  • Store a counter in memory (starting at 0)
  • Go letter by letter through the current name, increasing this counter by 1 for each letter, until you run out of letters
  • Store this new final counter in memory (5)
  • Add this final counter next to the previous counter to obtain the number 45
  • Store this number in memory
  • Store in memory the fact that you are now considering the last name in the list of names
  • Recover from memory what this last name is ('James')
  • Store a counter in memory (starting at 0)
  • Go letter-by-letter through the current name, increasing this counter by 1 for each letter, until you run out of letters
  • Store this new final counter in memory (5)
  • Add this final counter next to the previous counters to obtain the number 455
  • Say the answer is 455

You don't usually need to think in this much detail. In fact, when you're asked to explain your thought process, you'll rarely go down to this level of detail. But oftentimes, this is the kind of level of detail that you will need to think at in order to write computer code. The reason for it is simply that computers cannot think at a higher level than this.

But thinking in small steps requires training. Understanding how small these steps should be requires knowledge of what fundamental building blocks or concepts are available to you, as well as practice combining those building blocks into solutions to problems.

For example, in the solution above, I use a lot of 'store X in memory' or 'recover X from memory.' This is something that humans do naturally. In fact, you're probably not even aware of it, unless you're having a hard time remembering something. When programming, however, accessing and using information stored in memory is something that must be done explicitly.

The takeaway is that part of learning to code is learning to think in small steps and learning how small these steps should be, such that they can be easily translated into instructions that go into the programs we write. Acquiring this ability takes time.

 

Article continues below

 

Why Generalizations in Programming Takes Time to Learn

Another thing that makes learning to code hard is that programming requires you to learn to generalize well. Computer programs aim to solve classes of problems, not just individual problems. This means that, if you were to write a program to solve the letter counting task I described above, ideally you would write a program that works for any list of names given to you, not just for when the list is 'Mary,' 'Alice,' 'James.'

Many inexperienced programmers can find a solution to a specific instance of a problem, but have problems generalizing that solution to solve all similar problems in an efficient manner. However, these general solutions are exactly what make computers so powerful.

In fact, the ultimate goal of computer science, one could argue, is to create a program so powerful that it could solve any problem. This, of course, would be akin to replicating the human brain, something called AGI (Artificial General Intelligence).

 

example of a generalizationExample of generalization

Image Source: Exploring Generalization, Specialization, and Dependency in OOP, InfoWorld, 2016

So the takeaway here is that, while you may be naturally good at solving problems as an intelligent being, you're not necessarily good at generalizing our solutions to apply to similar problems. Developing this ability can be a slow process, thus making programming a slow skill to acquire. This is also where having some math experience can help, though I do believe that you can be a good software developer without necessarily being good at math, something perhaps a bit controversial in some circles.

 

Why Learning the Right Programming Patterns Takes Time

Here's an interesting thing: programming languages have very few words. In fact, you can read below the list of all Python keywords:

False, None, True, and, as, assert, async, await, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield. 

These are all the reserved words, as of Python version 3.7.2. You can use these words, and other words of your own choosing, to make programs that solve very complex problems. Compare this to an actual human language, like English, which has, by some accounts, hundreds of thousands of words.

Looking at it this way, it's perhaps more obvious that the difficulty doesn't come from mastering a programming language, but rather it comes from mastering the patterns. These patterns describe concepts that build upon other concepts to create ever more powerful building blocks that you can use to solve problems. Acquiring a library of patterns that you can use is a process that takes time. 

 

As a side note, while acquiring a library of patterns you can use to solve problems takes a long time, it comes with a surprising benefit: it makes it easy to pick up new programming languages. In fact, once you've mastered one programming language, you can pretty much teach yourself any additional programming language you want.

 

This is because, fundamentally, these building blocks are common across programming languages. It's also for this reason that I do think that novice programmers would benefit more, in the long run, from learning more about programming concepts in general, and less about specific libraries for a given programming language.

This last point is also part of my biggest criticism of most software "bootcamps" in existence today: they teach a language, not a way of thinking. They may be focused on Python, or Javascript, or even narrower, on a library like React JS. This can be useful to make someone immediately productive, and immediately hireable (though not always), but in the end they fail to teach students how to create solutions to problems in a way that they can be translated frankly to any programming language, and ultimately understood by computers.

 

Why Learning to Program Slowly is Actually a Good Thing

The difficulties I highlighted in this article are not the only ones that slow down the process of learning to program. There are, unfortunately, many other obstacles. Programming requires the ability to focus for long periods of time, something that is becoming more rare nowadays; it requires a very strong short-term memory; it requires the ability to think very clearly and it also requires the ability to sit in a chair for hours on end, which should not be underestimated. However, there are many options, such as Edlitera's programming courses, to help train you in these skills and learn programming at your own pace. 

 

Ciprian Stratulat

CTO | Software Engineer

Ciprian Stratulat

Ciprian is a software engineer and the CTO of Edlitera. As an instructor, Ciprian is a big believer in first building an intuition about a new topic, and then mastering it through guided deliberate practice.

Before Edlitera, Ciprian worked as a Software Engineer in finance, biotech, genomics and e-book publishing. Ciprian holds a degree in Computer Science from Harvard University.