Why Programming Is Hard

Lately I have been getting the feeling that people in general have no earthly idea what programming actually means. For reasons I cannot fathom, it seems to me that many people imagine HTML when they hear the words “programming”.

Not to say that HTML users (web developers) are not skilled; HTML is a Markup Language, not a programming language. Different purpose.

It bothers me a lot that many institutions that advertise themselves as “coding” are primarily Full Stack development, which is, more often than not, focused on web development. In my limited experience with it, web development concerns itself with how it looks and feels rather than how it works. That’s not to say there’s never any coding involved in full stack; there often is for the back-end of any particular website.

I don’t want to gatekeep web developers; web development is development, and full stack developers are in very high demand all the time. However, HTML should never be what the public perceives as “code”. Code runs; it does something other than make words on a page look nice.


Programming has to be one of the objectively most difficult career paths. Being a (competent) programmer not only requires extreme literalism, but also understanding multiple different ways of solving the same problem (paradigms) and an unending patience and endurance (for problem solving and debugging).

I have observed that some people think that programming is writing “code that only computers can understand”. This is awfully incorrect. Programming languages aren’t even computer code; (most) programming languages are designed to be, to some degree, human-readable. Programming languages are abstractions of how computers actually work to a more readable and usable form. What computers actually run and execute from looks more like this:

And even then, this is an abstraction. This is called Assembly Code, or in other words, the next step after Machine Code (which is literally just hexadecimal (base 16 numbers, which is a scale-up of binary)). Assembly code nor machine code is not typically what modern programmers write – although there are plenty of exceptions.

However, high-level programming languages, while they are supposed to be human readable, are still designed to instruct a computer on how to operate, so they do not look like human writing or speech. Take the simplest program one can make (in Java):

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); 
    }
}

This program writes “Hello, World!” to the console. This is the simplest program, but there is a lot going on here. You don’t necessarily need to know all of this to write a program like this, but if your syntax isn’t correct, your program will not compile or run.

On the first line, we can already see the keyword “class”, which is a very important structure in object-oriented programming – it’s often described as a blueprint for objects (which is its own subject…). On the next line, “public” is an access modifier, “static” is a keyword used for memory management, “void” is the method’s return type, “main” is just the name of the method (which, in this case, has to be “main”, since it’s the main entrypoint of the program), and “String[] args” is an array of strings (strings of characters) that is fed into the program – but it won’t be used in a program this simple. “System” is a package, “out” is a class, and “println” is a method that prints the provided line to the console, with a new line.

All of this. To write one line to the console.
Granted, this is because Java is a strict object-oriented language. This is what the equivalent looks like in Python:

print("Hello World!")

You can make it this simple in Python because, while it has an object-oriented approach to how it solves problems, it is not strictly object oriented; code can run outside of classes.

Different langues are not just different syntaxes – they are designed differently, they solve problems differently, and they work differently.

Object Oriented Programming is a paradigm, or in other words a collection of features and a design philosophy that dictates how you solve programs with a language. Remember, programming languages are not actual computer code; they are abstractions, designed to be easier to use and read than native machine code. So, the designers of a language might have different philosophies on how they want their language to be used, and being a competent programmer is being flexible with multiple paradigms.

Unfortunately, I have next to no experience outside of object-oriented languages, and I find myself struggling to understand functional languages, even when just reading about them. Going from paradigm to paradigm requires being able to have a complete mindset shift for how to approach a problem on the fly. It’s difficult for me to imagine being able to do that.


In my experience, there are 5 steps to solving any particular programming problem:

0. Understand the problem. This includes reading it, thinking about it, and probably splitting it up into multiple different problems, which will be solved in this same order later.
1. Set up the problem. Get the program to read the input/data. Create variables to store that data. This can also consist of finding libraries (code other people have written for you to use) and setting up your workspace (the software and place on your hard drive that you program in).
2. Solve the problem. Manipulate the data in the way that the problem requires. What this actually means will depend on the problem. If your problem has multiple parts, prepare the data for the next part.
3. Debug the program. Make sure that you code in step 2 works and gives you the output you want. There’s a good chance it doesn’t, or that you overlooked something, or that there’s a special case you didn’t account for. You or others might have to go back to this step long after your program is published, if a user finds a bug.
4. [Optional, depending on the context] Optimize the program. This one is easy to forget about. Especially in the professional world, if your program doesn’t run efficiently, then it will likely need to be updated to be faster/better. This usually means breaking the problem down in a different way, and solving it in a way that takes less time for the computer to execute. This can require going through each step again.

Each step requires significant brainpower, effort, and skill. Doing this as a career requires having the patience and endurance to do this every weekday. I know it gets easier as you get used to it, but the idea of accelerating myself into a workplace where this is the norm is extremely daunting.


So how the hell do you learn all of this? Better yet, how the hell do you even teach it? I don’t have an answer for you. As I said already, programming has to be one of the most objectively difficult career paths. I know this very well as someone who is just barely starting out in the development world.

I am not a competent programmer. This is usually the part where I say “yet”, but after writing all of this out, the task feels more daunting than ever. You see, I may be able to describe to you how programming works, and why it is hard – but I myself cannot execute when it matters. I might understand the syntax, and how a programming language is designed to be used, and how to solve programming problems, but I simply do not have the experience to be able to do it effectively.

Honestly, I feel like this for a lot of things. I want to make a separate post soon about how I feel like there is a massive disconnect between what I learn about something and my actual skill with the subject. It’s very difficult to talk about without my listeners thinking I’m being self-deprecating, but there’s a massive difference between knowing what I don’t know and thinking I’m hopeless/useless. Once again, the word “yet” does a lot of work here.