Posted On: 2020-10-26
Every programming task begins with a goal. Whether that's the simple "I wonder if I can..." of a hobby program, or the nuanced, detailed descriptions of a professional assignment, a programmer is always aiming to achieve some particular goal when they work. Yet, no matter how detailed that goal is - there's always more to the task than that. This additional work is, in many ways, where the developer's skills most manifest - but it's also often not as clearly understood or appreciated.
In addition to the stated goal of a task, there are also often implicit goals. The most obvious of these is performance goals: if the user gives up waiting for an answer, it doesn't really matter if the program would (eventually) give the correct one. There are also implicit goals about how the program will handle diverse data - often, programs will be written that behave correctly in the vast majority of cases, but then fail unexpectedly when the users have some unanticipated (but perfectly understandable) special circumstance*. Then, of course, software also has implicit security goals: protecting users from bad actors is essential - whether that's protecting networked software against direct attacks, or even keeping users from hurting themselves when they copy-paste something they found online**.
Software also has the interesting quirk of outliving its own documentation. Even when code works and meets all its implicit expectations, it must also be maintainable: easy to understand and update. Modern software is constantly changing, as are (for better or worse) the teams that work on it. Software that works today might not work tomorrow - as much due to the constantly shifting expectations of the users/business as the ever-progressing obsolescence of old technologies. Having clear, self-documenting code is essential for sustainable development of a living project - and a massive boon for whomever finds themselves trying port/update/remaster a "final" version of some software that depends on an obsolete operating system/framework.
On top of all this, software is often running in an inconsistent environment. Differences between machines, background activities devouring resources, and an ever-rising level of parallelization* means that every run of software is different from every other - even if all the user's actions are identical. Resiliency, robustness, and sane error handling are key to making software that behaves reasonably, even when the rest of the machine is (metaphorically) on fire**. Unfortunately, such attributes are often undervalued - as they can only be seen when they're missing, and even then they're unlikely to manifest in controlled situations.
As you can see, there's a lot more to programming than achieving the desired goal. Implicit goals haunt every step, threatening to subvert an otherwise adequate solution. The need for maintainable code also demands developers' attention, as they must put themselves into the shoes of the future coders. Finally, writing code for inherently unpredictable systems means that developers need to think about how their code will behave when the systems upon which it depends are not.
Together, this combination of demands creates lots of room for developers to grow and differentiate themselves. Where one developer may focus on anticipating implicit goals, another might focus on maintainability. Every developer brings their own unique mix of skills - both in problem solving itself as well as in these additional areas of focus. It is my hope that reading this has increased your appreciation for what developers do, beyond simply solving problems.