I suspect that drives a lot of the problems.
Also, super-long-tenured engineers can be detrimental. There can be a tendency to not document anything when you can always just ask one of the oracles of knowledge that originally built it.
The wrong type of super-long-tenured engineer is just going to be defensive and full of excuses about why something was built one way, even when the pain of using what they built is dragging down the whole organization.
They will push back on anything new and choose to add incremental blobs of crap code to their existing pile of crap instead of breaking things down and using their learnings to help design the new system
Once you start thinking about the code in terms of memorization you’re a hazard to your coworkers. It’s one of the reasons I like to try to move about on projects.
When you built the code you had to think about two or three concepts at once. Then new functionality added another concern, and another, and another. For you, each addition was one more thing on a pile you already knew.
For someone new looking at that code, they have to now juggle ten things at once, so they either run away, or they learn by breaking things. Which the frustrated tenured person may use as confirmation bias about how all the new hires are worthless and we should only trust senior people. When really the entire situation is your fucking fault.
I'm pretty guilty of this. The way I see it, I can either tell someone now why things are, or I can let them waste time figuring it out for themselves.
If you stick around long enough, eventually you become partially responsible for a collection of projects built by people who came, did a passable job, then left. I'm not keen on spending months rewriting a system just because the current one has some issues. And if it needs a new feature/update, I have no problem tossing a turd on the pile of crap.
Granted, I see the appeal of rewriting things. You get to spend 12-18 months building a new project the way that you want it, then leave once it is built and the maintenance responsibilities kick in. These people have never had to actually maintain software before, so they have no idea how to even write maintainable software.
They don't need to stay 20 years, but at least someone should still be there from beginning to end of a 5 year or even 2 year project.
Haha. So true. Isn’t the adage you’re either changing or dying?
I still maintain that most of the legacy of the dot com boom bust cycle was not developers learning bad habits, but managers figuring out enough lines of bullshit they can tell people to string them along for 18-24 months and getting promoted or a new job after everyone figures out everything you said is empty (lies).
That’s IMO the root of the tech debt problem. Devs ate it up, but they were coached as well.
Not even close. Can easily have three people manage the same project in a two year period.
That would be somewhere between stereotyping and pernicious pessimism, and at your tender age you don't want to think about yourself in either of those ways, so we'll wait to see if this person will actually deliver or not. Great route to burnout.
Wouldn’t we also need to blacklist a company that loses a programmer before the five year mark?
Some issues I found: 1) It took me years to clearly specify what clean code is. 2) I still haven't learned to effectively articulate its importance. 3) Except maybe onboarding time, I don't know how to measure its importance. 4) Cleaning up code is not rewarded. 5) Writing dirty code is often rewarded with promotions.
Agreed, the usability of tooling is important. Code is not just a tool to do a task, it is at once the tool and the communication to future developers.
Programmers, like anyone else passing through an educational system, self-select for strengths and avoid their weaknesses. Thinking is prized among programmers; thinking about how others think is most manifestly not prized.
There is also a demographic phenomenon. Each group rebels against something. (Parentheses, compilation time, memory management.) If the rebellion makes sense, it may result in progress. But to be well-designed, a rebellion must be consistent in its principles.
Safe code that still compiles and runs unchanged after decades is a measure of the real value of the design. Tooling that is partially or completely broken, or chasing faddish delights, is a sign of profoundly indifferent design.
I totally agree that many/most software organizations don't take it seriously. But I don't think that it's because of a lack of desire, I think it's a lack of even knowing it's a thing.
I put my skills in writing clean code in my most recent performance review but I didn't do a good job of describing it. It's also not something that is apparent to higher ups, but is readily apparent to colleagues who describe the code as a "joy" to work with.
I think we need to get better as an industry at measuring "Code UX" in a quantified way, and then that can start to be a meaningful area of progress that engineers can use in their career, which will motivate them to improve on that metric.
2) Unfortunately solving the problem isn't as straightforward as it sounds, because notions like "intuitive" and "clear" are hard to define objectively. Explicitness, constraints, and simplicity are pretty objective. But intuitiveness has to be considered in relation to the current and future team (languages/idioms they're likely to have in their head, domain concepts and background knowledge they're likely to have, etc) and will always be imperfect. Of course we should still try, and as you point out, many people don't.
Instead of jumping in every time they get stuck, make notes while they struggle a little bit. If they still don’t get it then intervene, acknowledge this seems to be more opaque than you hoped, bail them out, then take more notes about the interaction.
Maybe all you need is to switch to a synonym you mentioned in your explanation, or to homogenize argument order between some functions, or pluralize an argument as an affordance. Maybe you used jargon from a problem domain (eg, graph theory, linear algebra) and you need to think about whether you really expect everyone on the team to learn that jargon on top of everything else or maybe you should instead use terms from the requirements or application domain and leave the theoretical terms as comments in the code, or local variable names.
Or maybe your whole theory of organization is inside out and backward and you need a very different API that hides or telegraphs implementation details.
[1]https://backbonejs.org/docs/backbone.html
[2]https://underscorejs.org/docs/underscore-esm.htmlThe pendulum is swinging back from the overreaction to that, Java's famous AbstractSingletonProxyFactoryBean. As awful as that name is, I will take it any day over L(IH+GV).
I've worked on codebases built with UX in mind and codebases without, and it's a world of difference.
Code with UX has descriptive names, functions whose names intuitively describe what they do, using parameters that can't be accidentally misused. APIs are clearly delineated, domain edges clearly defined. Reading such code feels almost like reading a high level recipe, with the nitty gritty details available on demand using CMD-click. Weird edge case code is documented with a block comment explaining why it was done in this unexpected way. Nesting is minimal. Aptly named temp variables that only exist to aid readability are common.
And the irony of it all is that by eschewing code UX, you're mortgaging your future: making it progressively harder to maintain your codebase, and harder to bring new people up to speed. Changes take longer, and testing is more difficult as fewer and fewer people understand what it's doing.