A very different take – but I won’t express it until the end:
My generation was taught to sketch, then pseudocode (to quickly write in comments), then to write the code. To make it work, make it work well, make it rock solid and elegant. This evolutionary cycle allows you to incrementally iterate (evolve) your thinking. We started with assembly language and then worked upward.
Generally people are drawn to process heavy(logical) or interface heavy (psychological) problems and we tend to self-sort into those specialties.
There is a sort of class system to programming just as there is in building construction, and each ‘class’ has different needs. I have always preferred ‘stringy’ (LISP-y) languages. Some people prefer mathematical languages, and some operational languages.
So as in all fields we have Math > Operational > Verbal disciplines, and in our case, patterns, languages and tools.
I suggest a different criteria for the judgement of code:
1 – Code should be efficient to scan, then read.
2 – Code should be literary rather than symbolic whenever possible.
3 – When symbolic is necessary for performance or other reasons, it should be well commented.
4 – It should tolerate (survive) changes and produce informative errors rather than produce variations in outputs.
Most of us suffer from the long learning curve of trying to reduce to intuition the vast subtle variations in problems, patterns, data structures, languages, and operating systems. And we want something we can scan so that we preserve short term memory for the problem we are holding in mind. This reduction to intuition occurs only through repetition.
All old programmers are the same. All new programmers are different.
New programmers are cheaper and there are plenty of them on the market.
Most problems we talk about are merely the process of turning young/new programmers into older/old programmers by a process of disciplined daily trial and error.
Some people are very good and very fast from the beginning (the more mathematically inclined have superior short term memories, and lower frustration budgets, and lower costs of context change.) Some of us are the opposite. In other words, some people craft precise bricks and build with them, and others create designs and craft the bricks that fit.
The net result is this: Are you writing for yourself in the moment? Yourself in the future? Or are you writing for the poor soul who has to maintain or change it?
The ethics of programming is the same as international ethics of travel: if you wouldn’t say or do it in front of your mother, then don’t.
Its the silver rule of ethics: If you wouldn’t want someone to do it to you, then don’t.
When we code we often think (choose) using a little egoistic set of criteria. The solution is to think with ethical criteria because this forces us to self monitor the excuses we make out of personal convenience.
The problem is that we are all bound by time, energy, and mental exhaustion in a field requiring extraordinary mental discipline. A sort of economy.
In other words – the problem of programming is ethical and moral not technical.
Just like every other field. In the long term the ethical solution in all fields wins.