I’ve written before that programming has two audiences: the CPU and your fellow programmers.
There are also excellent articles, such as Suffering-oriented programming, that help align what your goals could be while programming. “Make it work, make it pretty, make it fast” is brilliant programming advice, and I’ve tried to take that advice to heart.
Sound programming advice
The programming advice suggests that the program targets the CPU first – in other words, “make it work.” Then the advice targets your fellow programmers, the people who have to maintain or look at the code: “make it beautiful.”
Once your code successfully meets its computational requirements and is understandable by the mere mortals we work with, then we zero in on how to make it perform well. That assumes there’s an actual need, and that “pretty” code means that it’s likely easy to find opportunities for improvement. Under most circumstances making the code “pretty” means smaller, isolated functions that make optimization easier.
I recently was talking with a friend online and he presented a problem that reflected experiences I’ve had as well. He was tasked to integrate a body of code that had been created without oversight from a team in a silo. The code lacked tests, and having been written in a silo, didn’t follow the same coding standards as the main project.
It’s a tough situation to be in. Integrating such code means trying to figure out what the entry points are, things that tests would show. Since there are no tests, you also have to trust that the coders actually fulfilled the requirements, because under ideal circumstances the tests would show that the requirements were fulfilled, too.
What would you do? What programming advice would you give?
Confronting without confrontation
Like I said, I’ve run into a situation like that. While I think I could have handled it better than I did, I also think I navigated the situation fairly well.
People don’t like to be confronted, and it doesn’t matter what they’re being confronted with. Dietrich Bonhoeffer had a really good observation: people can be stupid, but groups can be amazingly stupid. Worse, they are resistant to challenges, and this resistance grows based on how many people are involved. (Put another way: you can change a single friend’s mind fairly easily, but to change the minds of a gaggle of seven people is a challenge where angels would struggle.)
So, here’s what I did: I portrayed myself as the one who was challenged by their codebase. I didn’t comment on the actual code or how horrible it was. I asked how I could learn from the code, because I didn’t understand it.
“Where are the tests for this feature?” I asked, even though I knew there were no tests. After all, I might have been wrong. Asking where the tests were was a gentle prod to them about to what I needed from them.
Asking about their code in that way gave them a lot of leeway in how they answered.
They could point out where a test actually fulfilled what I needed, and perhaps I just didn’t see it? (In this particular case, no test existed and I knew it, but that wasn’t the point. I needed them to think about the possibility.)
They could also observe to themselves that perhaps the test didn’t exist, and as a requirement for handoff, maybe they could write one.
Testing is hard when you haven’t designed your code for testing, but that’s not your problem until you accept the code. My inquiry gave them an opportunity to revise their own understanding of the code, without dealing with my opinion of their code.
Of course, perhaps you don’t have the authority to request tests like this. In this case, you may need to request help from a stakeholder, someone who’s responsible for the delivery of the code. If so, point out to them that integration of the untested code introduces variable reliability — i.e., it’s unreliable, because you can’t assume it is reliable.
A conversation with a stakeholder about reliability might give you the authority to go back and have the conversation about structure and tests.
Programming advice psychology
Again, this conversation can be entirely inverted. Maybe they wrote spaghetti code and they’re proud of it – and who wouldn’t be? You simply ask that they write it so that you, of little brain, can understand it as easily as you can understand the code written according to your organization’s conventions.
“Wow, that 243-line function is awesome, but I don’t understand it. Can you show me how we could break it down and refactor into something that had smaller functions and composition? And this reference to ‘j’, is that an index? Could we name it what it actually represents? It’s a window handle? Please help me, I just don’t get it.”
This is all basic psychology at work. In a way, it’s manipulation — but we manipulate people in gentle and hopefully kind ways every day and in every interaction. We smile when we greet people, to trigger specific endorphins. We mention the good news first (or perhaps not) to create specific mindsets favorable to what we want. It’s not abnormal to use how people think and perceive for your own ends. Nor is it evil to do so when the result is a net positive.
Don’t be afraid to use psychology to help you program. It can be hard, because sometimes you can’t shout at people who might honestly need some shouting at. But shouting tends to be counterproductive. We must think about how to create the circumstances that enable us to get stuff done, rather than satisfy our egos by putting people in their places.