Hacker News new | past | comments | ask | show | jobs | submit login

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 this comment, though, that a ternary is more readable with newlines and indentation:

  return (a < b ? -1
          : a > b ? 1
          : 0);
That's the style I use, except for extremely short and ternaries where the verbosity adds nothing, like (A > B ? A : B).

In my view it becomes more complex to understand when there's a ternary inside the first branch, because then it's equivalent to if...(if...else...)...else... At that point I'd consider using if statements, if there is no reason to stay with an expression.




> 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:
           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 sane languages, because the nested ternary doesn't work the way you'd expect in JavaScript...


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


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

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.

(in both cases, because of the potential for stupid mistakes, I'd add tests)

But there's no single solution for all situations. High complexity software ? Concise will help out more. Low complexity software ? Write it out for clarity.


> 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) };
  }


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.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: