Live data from Hacker News

Clear is better than clever [pdf]

dave.cheney.net

151–160 of 335 posts

Re: Clear is better than clever [pdf]

#151

Reminds me of an early code review that preferred applying De Morgan’s law and being initially surprised. It was a small chat that started talks of the clever vs readability on a small team. Similar things would happen with say map(f) |> map(g) vs map(f |> g). My clev-dar just reminds me to ping the reviewer or leave a note.

Yeah. I always see the De Morgan's Law being used to make the code look prettier or look less complicated.

I'd say it's objectively prettier most of the time, but unfortunately that's exactly what introduces double negatives or other ambiguous stuff and makes the code more confusing.

It's a nice refactoring step, though: apply it, extract the condition into a well-named variable and test that condition.

Re: Clear is better than clever [pdf]

#152

Earlier quoted context omitted.

They are confusing and misleading to anyone new to your code base. But why should that be the main thing to be concerned about and prioritise? In what way are they "misleading"? Is it really the state of the industry where a new person cannot learn a codebase, has no time or effort, and cannot read a single line of the language they were hired to work on, and that's the person we should build everything for? Does it…

> Does it work like that in any other industry? Yes, it does. Imagine you were a new underwriter at an insurance company and your predecessor used the shorthand nomenclature for every detail on the accounts you're taking over, and failed to write out any of the detailed reasoning behind why they chose to approve or deny claims. How much longer would it take for you to be able to fill their shoes than if they had been…

Did you see that it was me quoting that exact quote as something to argue against?

I don't know what shorthand nomenclature of insurance underwriting is, but if it's a standard part of insurance underwriting then I would expect a new hire to be familiar with it, or need time to become familiar with it.

If it's something separate like actual Gregg or Pitman shorthand English which the one underwriter used personally, unrelated to underwriting skills, then I wouldn't compare that to a programming language's built-in ternary operators.

Re: Clear is better than clever [pdf]

#153

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…

I disagree. Reading the verbose example takes less time to understand, not just because the concept is clearer, but it is also visually easier to separate lines, even if that is 10 times as long as yours. If you see that somewhere, it will take a blink of an eye to understand, but your one line solution has to be read from left to right carefully considering colons and separating parts in your head.

Re: Clear is better than clever [pdf]

#154
post #113

Earlier quoted context omitted.

Ternary isn't the same as a branch and you want your this simple comparison function to get inlined every time

> Ternary isn't the same as a branch It should be. The C ternary is just an expression-oriented version of if/elseif/else. Languages with a functional bend simply make if/elseif/else an expression in the first place e.g. in Rust it'd be return if a b { Ordering::Greater } else { Ordering::Equal } Though obviously that specific version is an overly complex way of writing: return a.cmp(b);

i find it really odd that of all the knocking back and forth on this thread, you are the only person to suggest that using symbolic values for 'greater than', etc, improves readability.

Re: Clear is better than clever [pdf]

#155
post #142

Earlier quoted context omitted.

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

TypeScript does and it’s one of my favorite features.

Re: Clear is better than clever [pdf]

#157

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…

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.

Re: Clear is better than clever [pdf]

#158

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.

It's also a fallacy that a ternary operator is some impossible to understand concept that will make the code totally unreadable for everyone but you. C programmers should be fine with the use of ternary operators for something like the example shown here.

Re: Clear is better than clever [pdf]

#159
post #88

I agree with the sentiment, but not with Go's interpretation. To me, higher-order functions like map and reduce are much easier to read than the equivalent for loops and are less likely to have subtle bugs (off-by-one errors, etc.) because they more directly capture the author's intent.

I agree 100%.

In my experience, loops and recursion are lower level constructs that should ideally be used only in libraries (map, filter, limit, sum, distinct, etc [1]) and in hot code paths (for optimization).

Kevlin Henney makes a good observation on one of his talks about how "you have written all the loops you will never need in your life" [2], and those are constructs such as map/filterand friends, present in LINQ, Java Streams, Ruby Enumerables, etc.

His argument is that code made with those primitive is clearer than code made than procedural loops, because when you read it you don't have to "execute the code in your head".

I'd argue that using procedural loops is what's actually "too clever" here, despite being more verbose!

-

[1] I have mixed feelings about "Reduce". It is hard to use and, most of the time, hard to read as well. It's too low-level.

[2] https://youtu.be/APUCMSPiNh4?t=3317

Re: Clear is better than clever [pdf]

#160

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…

Personally I prefer (cond (( a b) 1) (t 0))

Or, if that's too many parens for you:

(mcond ( a b) 1 0)

The definition of MCOND is four lines of code and can be found here:

https://github.com/rongarret/ergolib/blob/master/core/ergoba...

Post reply on HN