Like of course, maintainable is good. But what makes code maintainable? When we're teaching new developers, what do we tell them to do to make their code maintainable? How do we distinguish between code that is maintainable, and code that is not maintainable? That's really the important thing; just knowing it should be "maintainable" doesn't particularly help.
And "readable" is even more complicated. Sure, there are some syntactic things that help readability—consistent indentation and spacing, good variable names, organized files, shorter lines. But beyond that it kinda breaks down. What makes a method readable? Well, probably a small number of lines, few branches, single purpose. That's good. But when you extend that to a codebase, you end up with code that you need to jump between a dozen methods to follow what happens in any given call. Is that readable? Or if you look at it from a class level, having a few methods where the whole chain of logic is in a single place is readable—but then you end up with giant god methods that do way too much. Is that readable? Presumably the balance is somewhere in the middle, but how do we recognize it? Just saying code should be "readable" doesn't really help.
Or "covered by automated tests"—definitely tests are helpful. Except for bad tests, which are harmful, and make fixing bugs or refactoring a painful process. So "covered by tests" can be good, or it can be bad, and adding the wrong tests can make your codebase worse. How do we distinguish between good tests and bad tests?
So I agree that the things mentioned are true about good code, but way too vague to help write better code.
"Readable", though, I can test simply by trying to read it. That is, I can test someone else's code by trying to read it. I can't test my own that way; as the author, I'm not qualified to read it for understandability, because I already understand it.
So in practice, this boils down to "Read each other's code. If you can't read it, say so. If they tell you they can't read your code, fix it." That is actually fairly simple to put into practice. It doesn't help you get it right the first time, but it shows you where you got it wrong, and tells you how to know when you've fixed it. That's a big step forward from "good".
Plus, some code is supposed to be more complicated than others, you can't always solve difficult problems with simple solutions. So unless you can understand the code and come up with a simpler solution, just complaining that it's too complicated is not gonna help anyone.
"Readability" may be a personal thing, but you'll reach convergence pretty quickly by following the approach you outlined. I see it as no different to something like writing, in that respect, in that an editor and a writer begin to converge on a style together without really setting out in the first place to do so.
More vague words can certainly help, when coupled with a culture where regular discussion of key values is part of operations.
So that's still vague: Suppose you have management that says, "We only want and reward 'good code'. And we think 'good code' at least consists of 'readable', 'testable' and 'maintainable' code. The rest, my dear operations, is up to you and your team. And you know what, please a Powerpoint a month about how you measure metrics based upon those vague words. But hey, make the measures durable, and don't try and fool us with 90%+ scores from the get-go."
The hope would then be that even 'vague' words can empower the team to measure and improve upon their own interpretation of those words. That could be different from team to team, from company to company. But at least it puts quality in the forefront and that place in the organization where it matters and is measurable / improvable.
This is why I also find it a good question for recruiting. People who only want results, but feel all time documenting is time lost, will give answers reflecting that. It might be an OK attitude, even winning in some circumstances, but would not fit in a quality-central culture.
My hunch is, it is crucial to keep developers and avoid situations where you have to maintain other peoples code as much as possible.
Just a quick idea, as I was writing this:
Lets compare software with fiction: assume, an author has written a quick draft for a story. It works great, it has more potential, some parts still don't fit in. Would you honestly take the story away from the author and give it to a handful of others to finish it and turn it into a bestseller? It is likely, that you get a mix of styles that gets worse and worse, the more people touch it.
Sounds familiar?
Some of the "voice" of the author might indeed be lost just because good copy editing normally is about 20% of a draft , but it could be argued that what's left is better for it.
I agree though that one should try to keep the overall tone/style the same
1. Start with an English description of algorithm
2. Write the code from the description
3. Translate the code back into English
4. Compare 3 to 1
Code that is easily translated to an English is probably the closest we can get to readable code.As a side note, this entire discussion of what makes good code is making me think of this[1].
[0] https://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf
[1] https://twitter.com/paulbaumgart/status/571788242174918656
Each part is interconnected to ensure quality and efficiency:
1. Maximum entropy means that your codebase should contain as much concentrated "information" as possible in relation to its size. Free of copy & paste code and repetitions that can be reused in libraries, methods and classes. This ensures less code to maintain , easier to spot bugs and easier to spot patterns.
2. Understandability (that includes readable): That means no blob classes or methods with an infinite number of purposes. Each layer of abstraction simple enough to keep in mind in its entirety.
3. Maintainable: It should be bug resistant, making it hard to do the wrong things and easy to do the right (for example putting required parameters into constructors rather than fields or properties). You should be able to replace and/or modify individual parts without side effects. Having as little code as possible also helps with this.
I think "covered by automated" tests are nice ... in some cases. It is far from a rule that they're a panacea for every kind of project, code and/or situation nor are all kinds of code wort the effort (models & algorithms: yes, UI: usually no). It also depends on the team and methodology.
That good code does what its suppose to do and should be bug free should be a given :)
If you think I'm using the term wrong I'd appreciate a reference, thanks
I actually think you should be verbose to the point of building a DSL-like syntax for your solution to improve readability. Even for instance addint small properties and methods that simplifies reading. It's much easier to read
if (CanWrite && WillFitDisk)
than if (File.Position != File.EOF && Disk.AvailableSpace > Buffer.Size)
Even if reusability of those small methods and properties aren't highSo I see it as "compact" as possible as long as you fulfill understandability and maintainability.
http://en.wikipedia.org/wiki/Entropy_%28information_theory%2...
I get that as developers, it really matters quite a lot whether the code is good. But on a higher business level, software development is a tool, and the most important thing to the business is that it works. Working well and making it better and more efficient are incremental improvements to the business... but code that doesn't work is a deal breaker.
Beautiful readable, testable, maintainable code that fails to meet the business need is still a failure.
Edit, in a less snarky tone:
If beautiful, readable, testable maintainable code is buggy, I'd bet money on the project being structurally sound, but the developer having failed to understand something about the business requirements. It'll likely take a little while to get familiarised with the structure of the code, and then some more time to identify (and fix) the parts of the business logic that are not working as expected.
Ugly, unreadable, untested, unmaintainable code that "works" usually doesn't actually work, not really anyhow. It works fine for the cases that make the bulk of day-to-day work, but is almost certainly going to fail horribly when you hit an unusual corner case, and fixing that corner case is going to be a pain, because the lack of structure and testing is going to make it really easy to accidentally break something, and really hard to identify that this has happened (and why).
Works: writing code should always have one purpose, deliver some value to somebody. Writing code that works, that it’s actually deployed somewhere making somebody happy is one of our top priorities. So we were kind of surprised every time a developer didn't include that item in the answer.
There's a business case for optimizing on each...and one for everything in between.
But a dimension you've missed... Code that works but isn't readable, testable, maintainable, will end up costing your business dearly. It's a nightmare for any developer working on any task - finding a bug, iterating, new feature, whatever - to have to work with a shitty code base. You could quantify the losses in $ stemming from having to work with shitty code... not only that but you'll have a lot more trouble finding technical help (I'm not alone that I'll ask in an interview "What's your technical debt like?", if the answer is bad, that's probably the end of the interview.)
On the other hand it also says: "To be fair, it’s also true that some of the developers had given that for granted (or at least that’s what they said when asked) but it can be symptom of some underlying problem."
So it's true that most of the developers asked assumed that the code was correct already but, in my experience, I've also seen in some cases (too many) that some developers believe that they are above everything and they don't worry enough about the value that the code should delivere.
I think it's the same symptom as the "throw over the wall" problem. Some developers tend not to worry about anything that is not coding.
If "better" means anything related to user experience, adoption or commercial success I think that correlation is about zero. Even the dumbest idea can be implemented by good code.
Elaboration tolerance is the ability to accept changes to a person’s or a computer program’s representation of facts about a subject without having to start all over.
This could make a good definition of what is 'good code'.
[1] http://jmc.stanford.edu/articles/elaboration/elaboration.pdf
Their team page at https://www.intenthq.com/about-intent/ looks like a classic British social class structure; the people-people, so-called "movers and shakers" at the top, the mere techies all scurrying around on the bottom rungs, and QA almost falling off them. Even the office admin is presented above all the technical people.
Anyway, negative, small-minded and snide observations aside, here's my totally unscientific summary of their completely scientific survey:
Readable
Simple (as in not entwined)
Functional/Verifiable
Maleable/Maintainable
Composable/Reusable
Efficient
But of course all of these aspects are also very subjective.Couldn't agree more.