Live data from Hacker News

Clear is better than clever [pdf]

dave.cheney.net

201–210 of 335 posts

Re: Clear is better than clever [pdf]

#201

Earlier quoted context omitted.

This I think is obviously personal preference, but to me nested ternarys are pretty readable as long as they're wrapped and indented. When they are, you basically get something that looks visually like a decision tree. This can read really nicely in situations where declarative style code fits better - for example embedding nested ternarys in JSX is quite a popular pattern for this reason. The caveat is, you have to…

Writing for yourself is a fallacy. We can all read our own code. Write for the next guy who has to look at it and figure out what is going on.

Who should you be writing for? Everyone is different. What's clearer for one person might be harder to read for someone else.

Re: Clear is better than clever [pdf]

#202
post #196
post #190

Earlier quoted context omitted.

All IMO: > However, I've never seen a convincing and objective description of clear code. I take "clever code" to mean "code that looks pretty on surface the but requires the reader to dig in in order to understand the intent". The problem with clever code is that it is misleading. It lacks empathy. You assume the next programmer will understand it at first glance just because it looks cool or pretty, but they'll str…

> When you break a method in three or four without adding REAL abstractions (a.k.a. "things you don't have to follow with the debugger to understand"), you're not making it easier to read, in fact you're making it harder because the reader has to jump around your code. Yeah, there's competing forces involved. If you push too many things together that do not belong together, then you end up with code that is hard to c…

> For example, manual memory management is a detail that should almost always be someplace else because it isn't relevant to solving the problem at hand. So we did this with garbage collectors. However, sometimes we need this detail present (high performance computing and/or constrained hardware ie video games etc).

That's a great example.

IMO looping is another case: I think it is clearer to use constructs like map/filter/group/sum/reduce instead of for/while/break/continue/etc. You only really need the procedural ones in hot-paths and such.

Concurrency too: in Javascript you had to nest callbacks and promises, and they were also "too noisy". Async/await helps you keep your code more readable. I think Fibers in Ruby (and other languages) were a good idea too.

-

> If you push too many things together that do not belong together, then you end up with code that is hard to comprehend.

That sums it up nicely.

Cross-cutting concerns should be abstracted (but not hidden), as they don't belong together.

Re: Clear is better than clever [pdf]

#203

It's interesting that the comparator function is one of the examples, because that's something which shows how people often confuse verbose with clear ; I think it's best written in a single line: return a b ? 1 : 0; That's one line, compared with the 10(!) of his proposed method using a switch statement. Having worked with some "modern" codebases, I think verbosity is a bigger problem that's become especially preval…

Nested ?: is hard to read due to the precedence. It's better to spend a few lines and break it up:

   return a  b
            ? 1
            : 0;
If that is too much:

   return a  b ? 1 : 0;
Other possibilities:

   return a  b ? 1
                        : 0;

   return a  b ? 1 : 0;

Re: Clear is better than clever [pdf]

#204
post #39

It's interesting that the comparator function is one of the examples, because that's something which shows how people often confuse verbose with clear ; I think it's best written in a single line: return a b ? 1 : 0; That's one line, compared with the 10(!) of his proposed method using a switch statement. Having worked with some "modern" codebases, I think verbosity is a bigger problem that's become especially preval…

Fully agree! Combinations of if/else can seriously damage readability and maintainability. I (all the time) face verbose code that pretend to be readable and that requires lots of attention just to find out you are setting a single variable across 10-20 lines. Example: if (cond1) { myVar = 1; } else if (cond2) { if (cond3) { myVar = 10; } else { myVar = 100; } ... } else { myVar = defaultValue; } * huge number of lin…

What we should be able to write in Go, but can't because the compiler (wrongly) imposes formatting:

   if      a       { v =   1 }
   else if b &&  c { v =  10 }
   else if b && !c { v = 100 }
   else            { v = d }

Re: Clear is better than clever [pdf]

#205

It's interesting that the comparator function is one of the examples, because that's something which shows how people often confuse verbose with clear ; I think it's best written in a single line: return a b ? 1 : 0; That's one line, compared with the 10(!) of his proposed method using a switch statement. Having worked with some "modern" codebases, I think verbosity is a bigger problem that's become especially preval…

It's not 10 lines, it's 8. Your implementation would need the function declaration and the } at the end too.

Now consider this:

        return a > b ? 1 : a 
Or:

        return a == b ? 0 : a 
Or:

        return b 
Are all these equivalent?

Figuring that out is much more difficult than their 8-line counterpart, at least for me. My eyes have to keep jumping from left to right in order to do the checks, like they would do in a piece of uglyfied javascript.

That said, context is everything: if your one-liner was the single line in a function called `comp` with `a` and `b` as parameters, I would not comment on it in a code review.

However, if this line was part of a bigger function, and if instead of `a` and `b` we had `someLongVariableName` and `someOtherVariableName` I would not approve the pull request until this "oneliner" was changed into something else (possibly a call to the `comp` function).

Re: Clear is better than clever [pdf]

#206
post #61

Earlier quoted context omitted.

> Combinations of if/else can seriously damage readability and maintainability. Yes, that's why for selections we usually use switch/case. But of course every programmer worth his money just knows that ?: is right associative and that '&&' is on precedence level 11 while '?:' is on 13. If that's not "clever code", I don't know what is...

> every programmer worth his money just knows that ?: is right associative I would hope every programmer worth their money are very comfortable with it, because chaining like this is a very common syntactic pattern in other people's code: cond1 ? val1 : cond2 ? val2 : cond3 ? val3 : other It is made less readable if you turn it into a right-nested mess of parentheses, so that is rarely seen. Just as nobody thinks of…

This came up recently on the Swift Evolution forum (which is the official forum for discussing changes to the Swift programming language). Dave Abrahams said, “[…] I keep meeting experienced programmers (really smart people!) that have no trouble reading [a chain of if/else statements] and yet are confused by the analogous ternary construction: [a chain of ?: expressions]”.

https://forums.swift.org/t/pitch-if-else-expressions/22366

Re: Clear is better than clever [pdf]

#207
post #157

Earlier quoted context omitted.

I agree, but would go with: return a b; This does the right thing, but removes the nested tertiary which to me is a big win.

What language? Those are different types.

I assumed C, and both values are of type int so they match.

Re: Clear is better than clever [pdf]

#208

Earlier quoted context omitted.

This is a natural point of disagreement. The question is what you're trying to do. Is this the lowest level of decision making in something like a large drawing application, or some CAD or financial package, then for the love of God, take the concise approach ! If you consistently take the longer approach, may God provide mercy on your soul (and a very large monitor) when you get to vector multiplication or matrix ma…

> If you're writing 3 business rules in something that's important and needs reliability and therefore should not have complexity ? Then it might be better to write it out. I'd give you multiple upvotes if I could for this. Absolutely agree with all your points. I'd add further, that if it's 3 important business rules, then sometimes expanding it further to have well-named functions and well-named variables is well w…

These are great examples, and I totally agree with both of you. However, the code most people write is somewhere in the middle, so it is a more subjective decision.

Re: Clear is better than clever [pdf]

#209
Using the keyword switch for successive condition testing is a travesty. Switching means taking one of several code paths based on a value. The problem with using a switch syntactic sugar for conditional testing is that the cases are not exclusive:

  switch {
    a > 5:
         ...
    a > 3:
         ...
  }
Here a > 3 is not reachable: it tests a condition that overlaps with a > 5 completely, and a > 5 is earlier.

This form of switch would be useful (and actually live up to the name) if the compiler were required to diagnose against overlapping cases, and also incomplete cases.

  switch {
    a  5: ...  error: domain of variable "a" not covered in switch without a default: clause
  }

  switch {
    a > 10: ...
    a > 5: ...  error: overlapping cases in switch
  }

Re: Clear is better than clever [pdf]

#210
post #39

Earlier quoted context omitted.

Fully agree! Combinations of if/else can seriously damage readability and maintainability. I (all the time) face verbose code that pretend to be readable and that requires lots of attention just to find out you are setting a single variable across 10-20 lines. Example: if (cond1) { myVar = 1; } else if (cond2) { if (cond3) { myVar = 10; } else { myVar = 100; } ... } else { myVar = defaultValue; } * huge number of lin…

I much prefer the if/else, thanks very much.

It doesn't matter what you use. If I can't understand your code quickly I'm going t fail your code review.

The use of if/else versus ternary operators is a matter of taste. If your composite of fucntions/methods reads declaritivly then the code will be easy to understand and your I dividual methods should also be small and easy to grok.

Post reply on HN