so some developers/managers see value in writing less code to get things done so that we have less code to maintain
This is a matter of losing sight on the actual goal.
What matters is lowering hours spent on development. That is measured in time (or equivalent effort), not in lines of code.
This is like saying that car manufacturers should build their cars with less screws, because it takes a non-zero amount of time to put each screw in. While that is pedantically correct, a car's market value is not defined by how many screws it does or doesn't have. Above all else, a car needs to be performant, safe, and easy to maintain.
The rest of the answer are examples of how clean code can lead to time gains.
Take an application (A) which has no logging. Now create application B, which is the same application A but with logging. B will always have more lines of code, and thus you need to write more code.
But a lot of time will sink into investigating issues and bugs, and figuring out what went wrong.
For application A, developers will be stuck reading the code, and having to continually reproduce the problem and step through the code to find the source of the issue. This means that the developer has to test from the beginning of the execution to the end, in every used layer, and needs to observe every used piece of logic.
Maybe he is lucky to find it immediately, but maybe the answer is going to be in the last place he thinks of looking.
For application B, assuming perfect logging, a developer observes the logs, can immediately identify the faulty component, and now knows where to look.
This can be a matter of minutes, hours or days saved; depending on the size and complexity of the codebase.
Take application A, which is not DRY-friendly at all.
Take application B, which is DRY, but ended up needing more lines because of the additional abstractions.
A change request is filed, which requires a change to the logic.
For application B, the developer changes the (unique, shared) logic according to the change request.
For application A, the developer has to change all instances of this logic where he remembers it being used.
- If he manages to remember all instances, he'll still have to implement the same change several times.
- If he does not manage to remember all instances, you're now dealing with an inconsistent codebase that contradicts itself. If the developer forgot a rarely used piece of code, this bug may not become apparent to the end users until well into the future. At that time, are the end users going to identify what the source of the issue is? Even if so, the developer may not remember what the change entailed, and will have to figure out how to change this forgotten piece of logic. Maybe the developer doesn't even work at the company by then, and then someone else now has to figure it all out from scratch.
This can lead to enormous time wastage. Not just in development, but in hunting and finding the bug. The application can start behaving erratically in a way that developers cannot easily comprehend. And that will lead to lengthy debugging sessions.
Developer A created application A. The code is not clean nor readable, but it works like a charm and has been running in production. Unsurprisingly, there is no documentation either.
Developer A is absent for a month due to holidays. An emergency change request is filed. It can't wait another three weeks for Dev A to return.
Developer B has to execute this change. He now needs to read the entire codebase, understand how everything works, why it works, and what it tries to accomplish. This takes ages, but let's say he can do it in three weeks' time.
At the same time, application B (which dev B created) has an emergency. Dev B is occupied, but Dev C is available, even though he doesn't know the codebase. What do we do?
- If we keep B working on A, and put C to work on B, then we have two developers who don't know what they're doing, and the work is bering performed suboptimally.
- If we pull B away from A and have him do B, and we now put C on A, then all of developer B's work (or a significant portion of it) may end up being discarded. This is potentially days/weeks of effort wasted.
Dev A comes back from his holiday, and sees that B did not understand the code, and thus implemented it badly. It's not B's fault, because he used all available resources, the source code just wasn't adequately readable. Does A now have to spend time fixing the readability of the code?
All of these problems, and many more, end up wasting time. Yes, in the short term, clean code requires more effort now, but it will end up paying dividends in the future when inevitable bugs/changes need to be addressed.
Management needs to understand that a short task now will save you several long tasks in the future. Failing to plan is planning to fail.
If so, what are some arguments I can use to justify the fact that more LOC have been written?
My goto explanation is asking management what they would prefer: an application with a 100KLOC codebase that can be developed in three months, or a 50KLOC codebase that can be developed in six months.
They will obviously pick the shorter development time, because management doesn't care about KLOC. Managers who focus on KLOC are micromanaging while being uninformed about what they're trying to manage.