I think the most readable code has no shortcuts and no tricks. I'll take unambiguous over concise or 'beautiful' any day.
I think the most readable code has no shortcuts and no tricks. I'll take unambiguous over concise or 'beautiful' any day.
In ('haute couture') software, the matter is up-ended. It is the 'comfort' of the developer that is a key consideration and not the reliability of the product. They don't wish to be "bored" with "boring" "boiler plate", etc.
I think the problem boils down to this: given the infancy of this field and the (still) primitive tooling available to support the mind-work, the field requires and attracts high percentile minds who are then tasked with building (again and again) what is in most cases glorified book keeping or plumbing systems. Naturally an outlet is required for self expression (which is a very basic need for high power minds) and that increasingly translates to need for 'bling' (thus the periodic migrations from the last "cool" stack to the new thing), and aesthetic 'elegance'.
YAGNI (You Ain't Gonna Need It) in specific comes from Extreme Programming, which is big on engineering discipline. E.g., its inclusion of Test-Driven Development and Pair Programming as practices. YAGNI isn't used there to reduce quality; it's used to reduce product complexity by only building features that are demonstrably necessary. Which, in my experience, helps with quality.
As to Lean, it's rooted in Lean Manufacturing, which comes from Toyota. An engineering-driven company, they used Lean techniques to reach quality levels way higher than competing car manufacturers, which gave them an enormous competitive advantage.
If people are using those terms to justify shipping crap, then they're doing it wrong.
How is extreme programming even remotely related to engineering discipline? It is a bunch of randomly tossed together practices with no proven value or efficacy, pitched by people who were incapable of doing the job themselves, to teach other people how to do the job. YAGNI is controversial at best, and often creates far bigger problems that what it was intended to solve. And that is when it is combined with the rest of the rituals it was intended to work with. On its own it isn't even recommended by the people who made it up.
>As to Lean, it's rooted in Lean Manufacturing
The name is anyways, but that seems to be about it. Lean manufacturing was about eliminating things that don't add value for the customer. The lean fad in software development seems to be most often applied by people who can't even tell you who their customer might be, much less what adds value for them.
>If people are using those terms to justify shipping crap, then they're doing it wrong
If processes rarely work and any failure is dismissed as "you're doing it wrong", then your processes are worthless. This is "any failure can be attributed to you not following our religion correctly" thing is one of the major things that killed XP.
Regarding the Lean fad, yes, all fads in software are shallow and foolish. I'm not interested in taking responsibility for shallow idiots, so if you'd like to yell at somebody about that, seek elsewhere.
The thing is, if the developer and/or code reviewer get bored reading boiler plate, they will pay less attention to the code, and will likely miss important things.
The point of redundancy in engineering is having multiple parts so that if one of them fails, the others can take over its burden. In programming this might be analagous to having multiple workers serving a queue of requests, for example.
The point of conciseness in programming is to provide consistency. You have a standard part that you can use the same way in many places. In engineering, it would be comparable to writing "use #7 widget" instead of drawing out the complete design for the widget in every place that you use it.
Ambiguity and conciseness are orthogonal concepts. Mathematics and formal proofs are very unambiguous, yet they are concise. On the other hand assembly code is unambiguous yet very verbose. Code has to convey two things:
1. "what should be done" to humans
2. "how to do it" to machines
Striking a balance between these two is difficult since it depends on each individual coder and the programming language. That's why there are so many syntax bike shedding wars because what's readable to one isn't necessarily readable to another.
The downside to that is the ambiguity sometimes causes bugs.
Formal proofs can be very long. It's an open problem today as to how to compress and decomplect them. It's extremely similar to the situation with programming.
I'm not sure that I intend to refute your argument at its core—clarity does not imply great verbosity in my mind—but instead to color your example a little more. As a perhaps more specific, powerful example one could consider "Proofs by the Book" of Erdös-style wonderfully short proofs. These usually demonstrate the interesting characteristic of having very high "compression".
also, a tangent about Erdos: Erdos was really good at posing problems. if his proofs are concise, it could have something to do with the problems he chose to work on. i'm not saying there's no book, i'm just saying that the most perfect, concise proof of some facts might still turn out to be very long.
I always think of human proofs as the words on the page plus a significant guiding practice and convention of mathematics. Some proofs require more of that than others. Internalizing these proofs is highly non-mechanical. But I don't think we disagree here.
http://www.newscientist.com/article/dn25068-wikipediasize-ma...
To your PSA, I would like to add: Never use the '!' operator at the beginning of a conditional. It's too easy to miss when reviewing or changing code, especially next to certain characters:
if(!llama) {
...
}
This is a tiny bit more text, and so much safer for maintainers: if(llama == false) {
...
} if (llama = false)
So use Yoda conditionals instead: if (false == llama)
Is that really an improvement over the original? As I've stated in my sibling reply, you are decreasing human readability for machine readability. if (llama != true)
instead?Or maybe you just use a not function:
if (not(llama)) if( ! llama) {
...
}
I don't know that it's an improvement, and my personal jury is still out, but I currently hold that it's better than the risk of the single equals bug that another reply points out, or the Yoda conditional that is the suggested replacement.if (foo == true && bar == false) ...
and it's so prolix it drives me crazy (especially if combined with a naming convention for Booleans, so it's obvious from the name that the value in question is Boolean). I feel like I'm in an epistemology class. "If the truth-value of the proposition p is true...."
If ! is easy to overlook, what about other unary operators? Perhaps we should write (0 - x) instead of -x, (0xffff ^ x) instead of ~x, and x[0] instead of *x.
Of course there are some better practices that would have caught it, but it was an easy mistake to make and an easy mistake to miss.
Another one I've come to enjoy is Java's insistence that I only provide booleans to my conditionals. It is a bit onerous to write "== NULL" a lot, but there have also been many times in C I accidentally forgot that the function I was calling did not return a boolean and so my test didn't do what I thought it would. For example, memcmp is not a true/false function but a negative/zero/positive function and so if you do not check "== 0" you can easily invert your logic.
That's the point. The programmer shouldn't have to remember to write code the Right Way, rather the language should be designed to avoid these ambiguities.
From a language design perspective, part of the reason this is such a good example is precisely because there is so little to be gained by allowing the braces to be optional.