Live data from Hacker News

Clear is better than clever [pdf]

dave.cheney.net

321–330 of 335 posts

Re: Clear is better than clever [pdf]

#321

Earlier quoted context omitted.

> because chaining like this is a very common syntactic pattern in other people's code If it's very common where you work, then run, don't walk, away...

"readability" is largely a matter of familiarity, so it's very hard to make such sweeping statements accurately. The difference between "common idiom" and "unreadable mess" is "common", not the code itself.

Strongly agree with this. My company has its own coding standards and openly acknowledges that they are not objectively "the right way to do it", because such a thing does not exist. Instead, they define rules to make our code (relatively) safe and consistent.

The Linux kernel has another set of rules that differ in numerous ways (e.g. not wrapping single-line statements under a conditional in braces). Their rules are not strictly better or worse, just different and define their set of common idioms.

Another thing that the MD said to me during my interview was "code ought to be boring, testing can be interesting".

Re: Clear is better than clever [pdf]

#322

Earlier quoted context omitted.

I've not heard of the supplier pattern, any chance you would direct me to a resource about it?

A Supplier is when a function needs a value, and instead of providing a value as an argument, you pass in callable: Foo(int x){return x+1} becomes Foo(Supplier x){return x() + 1}

Function that supplies value, can also encapsulate alot of data generation code. After that you can write a strategy to select which data generation algorithm (supplier) shpuld be used.

Thats my cause.

Re: Clear is better than clever [pdf]

#323
post #136

Earlier quoted context omitted.

> We are not using parchment anymore, there is nothing to be gained by saving a couple of lines. 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…

It really is a balance, and it's very hard to get it "just right". I mean I can appreciate a succinct oneliner (which is why I really like functional programming, doing a .map() instead of a for loop for example; it's a lot more compact without losing expressiveness, however, you do need to learn the lingo at first). When I first went from Java to Scala, I found that while you can perform the same logic in 10 times l…

> It really is a balance, and it's very hard to get it "just right".

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.

Re: Clear is better than clever [pdf]

#324

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…

In recent times, this verbosity has been accompanied by the (to me) insane decision in some JS prettifier plugins (opinionated even) of effectively putting one word per line. Now every if condition spans 4 lines on average. Delightful!

Re: Clear is better than clever [pdf]

#325
post #281

Earlier quoted context omitted.

Reading this discussion, I think one inescapable conclusion is that personal experience has a great influence on what people consider a desirable coding style. Among other things, people often infer something that isn’t actually there, because such an inference would hold in the programming language(s) or the more general programming model(s) they are familiar with. For example, there’s a big thread about the three-w…

I think the semantics of the language is also important. A ternary operator in a C like language probably is frustrating because it's some magic that was just shoehorned into the language with no rhyme or reason behind it. However, in a language like Perl 6, each magical operator has an intelligible semantic meaning behind it almost like a natural language. So when you mix and combine different operators, it starts t…

I think the semantics of the language is also important.

Yes. I suppose I’m arguing here that the importance of semantics is much greater than the importance of syntax. It’s not that syntax doesn’t matter, but these days I find myself much more concerned with what features a programming language offers than exactly what they look like.

A ternary operator in a C like language probably is frustrating because it's some magic that was just shoehorned into the language with no rhyme or reason behind it.

I’m not sure I can agree with that. The big difference between the ternary-if operator and if-else statements in the C family languages is that the former is used in expressions while the latter is used with statements. Sometimes that distinction is useful.

Re: Clear is better than clever [pdf]

#326
post #93

Earlier quoted context omitted.

I know ternary operators very well but I still have to think twice when I see them nested “You can't say don't use specific language features because some devs can't be bothered to learn them.” Would you say the same about C++? In my view it’s a good practice to use only a subset of a language consistently and not use all features. I have seen JavaScript code where I had to do research for half an hour before I could…

> I have seen JavaScript code where I had to do research for half an hour before I could figure out what it really meant. My view on this has flip flopped several times during my career. I think every spec has some dusty corners that most people don’t know about, but when a situation calls for it knowing about some obscure features can make your code far more readable. Sometimes it’s better in the long run to train y…

I've been taking the approach of writing code at the highest level of trickery/abstraction that is well-supported by my automated refactoring, debugging, and static analysis tools. This usually means keeping code quite simple. I can then play around with the code much easier if I need to make any changes, and I don't have to focus on the details much because they are quite explicit.

If something is so detailed that it gets too long to be quickly readable I extract it into a separate properly-named function.

I'm definitely drawn to using all the tricks of a language and I feel like it would be a great way to show off how smart I am, but I'm not sure its worth it for sacrificing comprehension and ease of adding stuff in later. Maybe if everyone that will ever work or use that code is top-notch, that would be a dream.

Re: Clear is better than clever [pdf]

#327
post #206

Earlier quoted context omitted.

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

There's are two pretty simple explanations for that.

1. It's rare, so not many programmers have the pattern matching built up to read it easily.

2. Chained if/else statements have the benefit of indentations helping to show structure. The moment you add newlines to help show structure, a chain of ?:?:?:'s becomes much easier to read.

Most ?: expressions I see are uses inline, such as foo(a ? b : c). When you do that, you sometimes have to mentally unwind "ok so if a... what's a? why a? ok, so if a, then foo(b), else foo(c)". Putting the if(a) up front means you're already thinking about it by the time you get to the function call. So I reserve using ?: for when the difference between the two outcomes is minimal.

Re: Clear is better than clever [pdf]

#328
post #296
post #218

Earlier quoted context omitted.

In Python you can write it like this: 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.

Python has its version of the ternary operator as well. It may look unusual due to the different order of the operands, but it works quite nicely, in my opinion: x = (-1 if a b else 0) This emphasizes the possible values that x may be assigned to.

I agree, the ternary style is better for this sort of variable assignment situation. Usually if I am using the above pattern I am calling different functions as the result of the conditionals.

Re: Clear is better than clever [pdf]

#329

Earlier quoted context omitted.

I've not heard of the supplier pattern, any chance you would direct me to a resource about it?

A Supplier is when a function needs a value, and instead of providing a value as an argument, you pass in callable: Foo(int x){return x+1} becomes Foo(Supplier x){return x() + 1}

Thanks.

Re: Clear is better than clever [pdf]

#330
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…

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 are worried with all the cases, you can very easily display your code as a truth table with nearly no overhead in this way:

  myVar =
    (!cond1) && (!cond2) && (!cond3) ? myValue_0 :   // case 0 0 0 blabla 
    (!cond1) && (!cond2) &&  (cond3) ? myValue_1 :   // case 0 0 1 bla
    (!cond1) &&  (cond2) && (!cond3) ? myValue_2 :   // case 0 1 0 blablabla
    (!cond1) &&  (cond2) &&  (cond3) ? myValue_3 :   // case 0 1 1 
     (cond1) && (!cond2) && (!cond3) ? myValue_4 :   // case 1 0 0 
     (cond1) && (!cond2) &&  (cond3) ? myValue_5 :   // case 1 0 1 
     (cond1) &&  (cond2) && (!cond3) ? myValue_6 :   // case 1 1 0 
     (cond1) &&  (cond2) &&  (cond3) ? myValue_7 :   // case 1 1 1 
                                       defaultValue; // uninteresting default (null, -1...)
Post reply on HN