It's not about the line count, it's about expressing the main idea clearly and succinctly, which this code does.
My nitpick would be with the language constructs themselves. The ternary operator is simply a crutch for lack of an if-then expression returning a value.
if a < b then -1 elsif a > b then 1 else 0
Or can add some white space to make the structure a little more clear: if a < b then
-1
elsif a > b then
1
else
0
end
Expressions like the ternary operator micro-optimize by replacing tokens recognizable as natural language words with arbitrary punctuation. But that's a language level complaint, which you generally don't have any control over once you've started the project or when editing existing code.It's far from "arbitrary" --- and I suspect that this dogmatic, misguided way of (not) thinking about it is responsible for the majority of the complaints and aversion, since as others have mentioned, it is completely equivalent in structure to if/else!
What do I mean by "far from arbitrary"? Well... what is the character used in basically all Latin (and even some widely-used non-Latin) languages to denote a question? I've already used that character twice in this post so far, and you should've found the previous two sentences to be pretty clear, so stop pretending the ternary operator is something scary and "unreadable" and see it for what it is: it is literally asking a question!
understand ? done() : keep_thinking();We ask questions with ? but we don't offer alternative answer to the question with :. If anything, maybe it should be ; or even .?
I disagree. I find no clarity in using nested ternaries, but I understand it's a matter of opinion.
x = if | a < b -> -1
| a > b -> 1
| otherwise -> 0
(and `cond` in lisps)Thats very subjective. As a beginner dev, the ternary series is almost un-understandable for me. While the if/else blocks are far easier to glance at and digest.
if a < b: x = -1
else if a > b: x = 1
else: x = 0
Which a lot of people seem to hate for some reason, but I always appreciated the compromise between terseness and clarity. x = (-1 if a < b else
1 if a > b else
0)
This emphasizes the possible values that x may be assigned to.This is not what the OP is talking about - we are not using parchment anymore, but we still have the same brains, being able to fit more code in our head with less i/o allows is a more holistic view.
There is a balance in between terse and verbose that produces a reasonable length of code for what it is doing, and that is subjective, to the individual and the code - so you are never going to agree on everything. But I say fuck no to people who want to lower everything to the common denominator, that is mediocrity, I don't want my grandma to be able to read the code if it makes macro comprehension horrible to the point of making it unmaintainable spaghetti.
When I first went from Java to Scala, I found that while you can perform the same logic in 10 times less lines of code, each line is also 10 times as powerful and complex. A random example I found in code from back then:
private def fetchDevices = (for (device <- devices.find()) yield device.getAs[String]("deviceId").get).toList
Super concise but at the same time the code doesn't actually do much as far as I can decode now, it's a lot of type wrangling.Yup, and you will find bad examples at both ends of the spectrum. And sometimes it doesn't even have anything to do with terse vs verbose, it's just bad code, not because of that one part of code but because of the context requiring it - just like in your example, I don't know scala, but if it's doing a lot of "type wrangling" then the real problem is probably further upstream from that point in the code, and no amount of terseness or verbosity is going to make it more clear - we are only discussing one dimension of the many subjective and objective dimensions that make code clear or confusing.
On that same vein, if a ternary operation is going to throw someone for a loop, I've got some bad news about their career in programming.
Because when something is expressed in 10 lines explicitly, generally you can simply skim over the code to get an idea of what's going on without having to go into the details.
"Smart and clever" code, like using nested ternaries, demands you to focus and try to figure out what is going on.
Which is why important details get missed when reviewing verbose code.
>On that same vein, if a ternary operation is going to throw someone for a loop, I've got some bad news about their career in programming.
You're right about someone having and issue if they can't understand this on it's own. What was the last application you worked in where that single line is all you had to understand to accomplish whatever task you were working on?
Exactly.
The bigger constructs expressed in functions, classes, etc, are where the attention should really be.
The smaller ideas expressed in single lines of code are, should be, insignificant in terms of cognitive load.
There are some exceptions to this, in particular very high performant code. We all know that "premature optimization...".
It's a question of trade offs but you cant entirely ignore one or the other
You don't read ten lines, you decode them. If it's ten simple lines, decoding them is easy. If it's a nested ternary, it's a lot more cognitive load - unless you're used to nested ternary expressions.
However, I'd say it's a fair assertion to make that most people aren't used to reading nested ternaries.
And I think that's what Go (and this presentation) is about; you shouldn't need to get used to a certain code style to be able to decode it. You should be able to open up a file and not be surprised. If I were to come across a nested ternary, my first reaction is a raised eyebrow and a "wtf?". The wtfs / hour is one of the metrics that Go language is based on.
Parchment, no, but do you not value vertical terseness when evaluating a function for code clarity?
Personally, I find that ternary example you posted to be terrible code. We are not using parchment anymore, there is nothing to be gained by saving a couple of lines.