Introduction to the Philosophy of Software Engineering 

Introduction

There are plenty of guides, books, courses to teach people how to program, but there aren’t any resources to teach one how to think like a programmer (or The Philosophy of Software Engineering). I feel like this is the missing piece to a person’s journey to becoming an expert software engineer. Software engineering isn’t a simple mathematical problem where if you learn “how to program” you automatically become an expert programmer, some creativity is required. However, creativity cannot be taught the way math is taught; I believe the key to teaching creativity is through mental framing. Framing is like inception, by planting a general idea, it helps coax ones imagination to veer towards that general line of thinking.

Motivation

We all have to start at the beginning, before we’ve learned any bit of code. What drew you to want to learn how to program? Remember this well; this is the foundation upon which you build. This is important for if your motivations are impure, you must admit that your path to expertise requires less-than-pure activities.

To use an extreme example, if your motivations is that you want to become wealthy and you’ve chosen software engineering because that field pays handsomely, then you should not shy away from abusing dark UX to effectively scam people (think: fake ads that convinces people to purchase antivirus software that’s actually spyware). While I do not condone this sort of behavior, I must point it out because there will be people who have purely financial motivations. They will justify to themselves that their motivations are pure and thus socially acceptable. This presents an issue because there will be cognitive dissonance between this person and others; and in the context of needing to collaborate, all parties involved must make it known their true intentions. Consider the case where you’re looking for another member for your team, you want this person to share similar goals and thinking as you so that you can work cohesively together.

Where to start?

As mentioned previously, there are plenty of resources for learning programming. Any of them are fine as long as you keep in mind that you should not believe everything verbatim. This is where “thinking like a programmer” is important. If there was an objective way to learn software engineer and become an expert at it, there wouldn’t be any debate or discussion about how people should learn it; it would simply be a matter of telling everyone to follow the same syllabus. The fact that it’s not as simple as that indicates that an objective answer to “how to learn software engineering” is not a solved problem.

The practice make perfect fallacy

There’s a stark difference in apparent skill when you compare an artisan with an assembly-line worker. Though the assembly-line worker may have the finesse and speed of someone who has practiced the assembly of a particular component, they generally lack the ability to creatively adapt to circumstances; this is not a knock on the person rather the motivations of the company training the person. The need for precision automation is typically devoid of creativity, thus the scope of their domain is very narrow, but they are able to outperform humans in that narrow scope. Most forms of education treats students as if they are automatons being trained rather than treating them to be artisans.

This is where the fallacy comes into play. We’ve traditionally focused on the “how” rather than the “why”; opting to focus on repetitive practice to ingrain a certain set of actions into our psyche as if it’s instinctual. The thinking behind that is that once a series of actions becomes instinctual, the logic (the “why”) will become apparent (consider the tired tropes in movies such as The Karate Kid).


Following up on The Karate Kid, many instances of this kind of fallacy is apparent in the study of martial arts. More recently, there’s been many cases of various martial arts being exposed as fake or ineffectual. This is caused by a few factors:

  • Faith - one typically starts learning a martial art because one already has interest in said martial art. This exposes you to blind faith. Such faith subjects you to confirmation bias and become easily manipulated through suggestion. You cannot help but believe that what you see is real, thus you end up convincing yourself that you are also being affected by the skill of the martial artist. This is akin to hypnotic suggestion.
  • Poor sparring - sparring is problematic because the intention is that you develop muscle memory for all of the possible scenarios you might find yourself in and instinctively know how to respond. However, the responses are substandard because sparring may subconsciously cause your practice-foe to give into your movements prematurely, thus, you will be convinced that you performed the action correctly, but given a situation with an unwilling opponent (an opponent that actually fights back) you will fail to actually execute your actions correctly.

It’s not hard to see how these fallacies may apply to learning how to program (or any other technical skill for that matter). Since the subject matter is something that most people do not understand when they first approach it, they would often religiously accept whatever teachings experts impart on them. And since these experts also had undergone the same path to become experts, it reenforces bad practices (akin to poor sparring). This is not limited to the field of programming, rather, it’s an issue that plagues the entirety of education. We mostly focus on teaching kids the “how” before teaching them the “why”.

Start with “why”

If rote practicing is not the way to go, then we must start with the “why”. Programming, like any other invention, was made to solve a problem (many problems in fact). So to have a good grasp of programming concepts/language features/etc, you must understand the problems that were already existent that lead people to invent a programming construct that solved such problems; such programming constructs were not invented in isolation looking for a problem.

The speak straightforwardly, when starting to learn how to program, you should not worry too much about learning how to program proficiently; learn just enough to be able to write simple programs. After that, come up with questions you’d like to know about programming; anything will do; the point of this exercise is that we often expect to be given tools for which we’ll try to use to solve problems that we have, but, as mentioned before, these tools were created explicitly because the problem already exists. So by being able to wonder about programming without being given the tools, you are forced to think about a problem you might be thinking about, and how programming can apply to it.

Once you have these questions, approach them as if you’re trying to research the answer. If no one has the answer, then you should think about how you would approach the problem; perhaps breaking it into parts and inquiring about each part will result in answers to those partial problems.

Some of these questions might result in an actual program application, for example, if the question was “how to program a game?”. It is through learning how to program by using programming to answer questions that we have about programming will be be able to gain the practice needed to eventually become proficient in programming.

Next: what languages to learn?

In the next chapter, we’ll discuss what programming languages you should learn.