Live data from Hacker News

Clear is better than clever [pdf]

dave.cheney.net

141–150 of 335 posts

Re: Clear is better than clever [pdf]

#141
post #138

Earlier quoted context omitted.

I disagree, what is "saved" is your time when reading/understanding... why spend time to read 10 lines and figure out that it actually does what a simple ternary operation would accomplish?? 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.

These are both extremes and both bad. The 10 line switch statement to switch a variable is a high cognitive load for no good reason but so is a nested ternary under pretty much any circumstances, but especially with single character variables and magic numbers. >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…

> 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...".

Re: Clear is better than clever [pdf]

#142

Earlier quoted context omitted.

You can write it without resorting to one-line conditionals: if(cond1){ myVar = 1; } else if(cond2 && cond3){ myVar = 10; } else if(cond2 && !cond3){ myVar = 100; } else { myVar = 4; } But when I encounter this kind of situations I have other problems than code formatting anyway: with 3 conditions you have 2^3 possibilities to check: are you really really sure (!cond1 && !cond2 && cond3) should give you defaultValue…

If you're running through that many conditionals, it may be clearer to work them into a state enum that you can use with a switch.

Golang doesn't have enums

Re: Clear is better than clever [pdf]

#143
post #116

Earlier quoted context omitted.

As long as verbosity is meant to make your code more explicit I'm fine with it. 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.

I disagree, what is "saved" is your time when reading/understanding... why spend time to read 10 lines and figure out that it actually does what a simple ternary operation would accomplish?? 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.

This is what good function names and default code folding is for...

Re: Clear is better than clever [pdf]

#144
post #79

Earlier quoted context omitted.

I wouldn't call that example nested; I'd call it sequentially chained, and I think that pattern is quite clear even with many conditions in the sequence. That pattern is the expression equivalent of if..; elsif..; elsif..; elsif... Writing it out in long form using actual if statements doesn't add much clarity, and costs in verbosity, as the OP says, macro-clarity versus micro-clarity. I agree with the sibling to thi…

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 worth doing, even if the business rules are trivial logic:

  // This rule was recommended by the accountant on 2019-05-06
  // and must be reviewed by the CFO before release.
  function receipt_needs_itemised_tax_record(amount: Money): bool {
      return amount >= 1.00;
  }

  // Show itemised tax records on receipts that need it.
  if (receipt_needs_itemised_tax_record(receipt.total_paid)) {
      ...
  }
Versus:

  // Writing this and other low-level code in 25 lines per function
  // does not make the 10kloc rendering library easier to understand.
   function transform_pixel(bg: RGB, fg: RGB, opacity): RGB {
      opacity = clamp(opacity, 0.0, 1.0);
      let blend_bg = 1.0 - opacity, blend_fg = opacity;
      return RGB { r: clamp_rgb(bg.r * blend_bg + fg.r * blend_fg),
                   g: clamp_rgb(bg.g * blend_bg + fg.g * blend_fg),
                   b: clamp_rgb(bg.b * blend_bg + fg.b * blend_fg) };
  }

Re: Clear is better than clever [pdf]

#145
post #141
post #138

Earlier quoted context omitted.

These are both extremes and both bad. The 10 line switch statement to switch a variable is a high cognitive load for no good reason but so is a nested ternary under pretty much any circumstances, but especially with single character variables and magic numbers. >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…

> 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 ver…

The bigger constructs are made out of these smaller pieces. Focusing on just the high level abstractions will end up with your application being difficult to fix when something lower level breaks and focusing on just the lower level code will cause your application to end up unscaleable or refactorable because of poor design.

It's a question of trade offs but you cant entirely ignore one or the other

Re: Clear is better than clever [pdf]

#146
post #142

Earlier quoted context omitted.

If you're running through that many conditionals, it may be clearer to work them into a state enum that you can use with a switch.

Golang doesn't have enums

Neither does JS, but there are ways to accomplish the same thing[0].

[0] https://stackoverflow.com/questions/14426366/what-is-an-idio...

Re: Clear is better than clever [pdf]

#147
post #78

Earlier quoted context omitted.

I would make the exception that if you judiciously indent then across multiple lines, to reflect the nested structure the way the if/else equivalent would, then they're fine. But yeah, nested ternaries on one line are impossible to follow.

If you even need to indent them then why you don't write a full if else statement instead? Nested ternaries shouldn't be used at all.

For languages in which if/else is unfortunately only imperative, not an expression

Re: Clear is better than clever [pdf]

#148

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…

Your single line is terrible code.

Re: Clear is better than clever [pdf]

#149
post #79

Earlier quoted context omitted.

I wouldn't call that example nested; I'd call it sequentially chained, and I think that pattern is quite clear even with many conditions in the sequence. That pattern is the expression equivalent of if..; elsif..; elsif..; elsif... Writing it out in long form using actual if statements doesn't add much clarity, and costs in verbosity, as the OP says, macro-clarity versus micro-clarity. I agree with the sibling to thi…

> I agree with the sibling to this comment, though, that a ternary is more readable with newlines and indentation: I think it's even clearer like so: return a b ? 1: 0; Conditions/guards on the left, values on the right. So I emphatically disagree with the OP that nested ternary expressions are never ok. In most sane languages with proper precedence and evaluation order, they work great when formatted as above. I say…

I think your version is reasonably clear, but it won't survive automatic indentation in any tool.

I use the parantheses the way I do, because editors will auto-indent the code that way. In other words if I press in Emacs, things won't move around in my example, so I know it's indented properly.

However, within that style, some people do prefer to put the operator at the end of a continuation line, and some prefer it at the beginning.

Re: Clear is better than clever [pdf]

#150
post #55

Earlier quoted context omitted.

The multi-line comparators are definitely clearer and more readable to me. The 10(!) lines of code you referenced are actually only 8(!) lines compared to your 1(!) line because you included the function declaration and the final brace in your count. The line you proposed is 34(!!) characters wide. I wonder if your statement will continue to grow past 80(!!!) characters as your operand expressions grow in width? Will…

Maybe you'll prefer return (a b) ? 1 : // a greater 0; // equal

still less clear
Post reply on HN