Hacker News new | ask | show | jobs
by Dewie 4376 days ago
> Developers always seem to be complaining about having to type this or that, when they should be much more concerned with what they have to read!

Or maybe they find terser syntax to be more readable. If verboseness was always more readable, if not necessarily more "writable", than terseness, then no one would have a problem with Java since it has good IDE support, including autocomplete and generation of boilerplate code. But it turns out that it's not just a matter of being lazy typists.

3 comments

There is readable based on each character such as semicolons, dots or curly braces and there is readable based on the shape of code.

That is two separate levels. When you first glance a page of code the first time in 1 second, you should tell what the structure of the program is. How many blocks (for/while/if) it has. How many functions, how big they. You haven't yet had time to read each individual character. That is one level.

Here variable and ambiguous indentation rules get in the way. If there is non-uniform, non-standard indentation then you have to start reading individual lines in detail. If there is standard indentation then it doesn't even matter about little commas and semicolons, it is a level higher than that.

Then past that it is about individual functions, classes, modules, and what have you. Then it becomes about == vs = or . vs , and so on. If there is ambiguity there it could be harder. Like in Python I added a , at the end of a some variable. So that turns it into a tuple. And it resulted in a strange exception down the line. In C the = vs == is notorious. But there are others. None of this make the task impossible, but just slightly harder. The problem is that if this is done many many time over the course of a lifetime of a piece of code. Maybe it take 10 extra seconds for reader to understand the code, that multiplied by thousands of times will add up.

That is what's known as a straw man argument. Nobody said verbosity always improves readability, just that it's easy to get too terse, just as Java demonstrates it's possible to get too verbose.

I'm pretty comfortable writing complex regular expressions, but I don't know many other developers that are and I certainly don't like trying to grok anything longer than about 10-15 characters that I didn't write in the preceding 15 minutes. This is a perfect example of where terseness is fine for simple problems, but it does not scale.

I already mentioned Go because it has a pretty terse syntax, but one that is very carefully optimised for readability. One of the things the designers of Go are careful about is not adding too many operators, keywords, or usage rules to the language, which keeps everything nice and simple.

Rust OTOH seems to have a metric boatload of operators that work in different ways depending on the specific context. That's a recipe for a ton of cognitive load, which isn't helpful for writing code, but reading suffers even more.

I don't yet know enough about Rust to say whether this is as bad as operator overloading in C++. As I said, I will reserve judgement until 1.0 because it's entirely possible things will change drastically before then.

> Rust OTOH seems to have a metric boatload of operators that work in different ways depending on the specific context.

What operators does Rust have that Go does not? I believe Rust has no more operators than Go.

This is just my impression based on those tutorials I've looked at so far; I've decided to put off learning it properly until 1.0, whereas I know Go pretty well. IIRC, the move semantics and lifetime annotations were one area that stuck out as pretty heavy on context-specific operators.
If anything Rust has been busy removing operators. As far as I can recall, move semantics have no operators at all (someone who remembers better can probably correct me on this), and lifetime annotations are just 'lifetime (I suppose you could consider ' an operator?). Rust is also LL(1), so it was a very explicit design decision to have as few context-specific operators as possible (indeed, a few suggestions for possibly more intuitive syntax have been decided against for this reason). So what you're saying really hasn't been my experience with Rust at all. In fact, the only really hard thing about Rust, from my perspective, is the semantics, not the syntax :)
Exactly why I'm reserving judgement for now.
Move semantics don't have operators; they happen automatically invisible. Lifetime annotations are not part of operators; they're part of types. The only operator is the same as in Go, &.
> That is what's known as a straw man argument. Nobody said verbosity always improves readability,

You're right.

Simple/common ideas should require terse syntax. Complex/rare ideas should require verbose syntax.

Prefer "x = y + z" to "ADD y TO z GIVING x".

Prefer "[[NSThread alloc] initWithTarget:t selector:s object:o]" to "pthread_create(&p, &a, &f)".