Hacker News new | ask | show | jobs
by tomp 3211 days ago
That's terrible, to have semantics depend on such a tiny syntax change that's so easy to miss.
9 comments

It's actually super nifty and IMO a great feature. However I think one of the reasons it works so well is that Rust is statically and very strongly typed, in a more dynamic language it would be hard to keep track of what's going on.

An other reason it works is that almost everything is an expression in Rust, including things like `if` statements. So for instance you can write:

    let message =
        if auth_ok() {
            "success"
        } else if tries < 3 {
            "try again"
        } else {
            "failure"
        };
If you add semicolumns after the strings the `if` will always evaluate to nil here.

Note that this won't work if one branch returns string an and other returns an integer for instance since the type of "message" must be known at compile time.

It also works well for getter functions and lambdas, for instance:

    fn is_empty(&self) -> bool {
        self.len == 0
    }
or:

    list.sort_by(|a, b| a.key < b.key);
This way you focus on what's important.

I can see where you're coming from though, it's easy to dismiss this feature as a bad idea on paper, especially if you've been traumatized with Javascript's insane handling of semicolumns. In practice however it's a rather useful sugar and so far it's been harmless in my experience. It basically makes the language more lispy.

I read your comment more as an endorsement of implicit returns. Make no mistake, I love those. I've been using them most of my life, first in OCaml and then in Scala.

I just think that using the semicolon to make the function return unit instead is problematic. It would be better to have the type system guide that decision, like in Scala. It would be even better to have an explicit `ignore` function or something (like in OCaml) to signal to the compiler that you really want to ignore the value and you only care about uthe side effect. I mean, why would you ever write just e.g. `a < b;`?

> I just think that using the semicolon to make the function return unit instead is problematic.

Agree. The idea to attach additional semantics to ; is completely nuts, especially as ; is mandatory in Rust (usually, there are odd corner cases where it is not allowed).

Just get rid of mandatory ; completely and let the type system handle the rest.

; is used to separate statements, how do you propose to get rid of that?

I guess you could use significant newlines like python but I never really liked that. I think Rust's compromise is pretty decent.

In particular it's the first time I hear people complaining about it, so far most users (myself included) seem to be praising it. Javascript's handling of semicolon is nuts, I wouldn't say Rust's is.

It's 2017, I'm not placing ; by hand anymore.

We have computers they are perfectly able infer them for me.

> Javascript's handling of semicolon is nuts, I wouldn't say Rust's is.

- JavaScript does insane things, as usual. This doesn't mean every implementation of semicolon inference has to be that bad and broken.

- Rust goes the other way by pretending it's still 1990.

There are plenty of languages out there that handle semicolon inference perfectly fine.

(Heck, I even let the IDE show me where the compiler has placed them.)

IANAPLRESEARCHER, but to my understanding, it actually unifies the semantics. The return value is always the result of the last expression, and its type may either be something non-trivial, or `()` which is what `expr;` returns.

This makes it easier to write and use generic code for which you don't know the return type (could be `String`, could be `()`), without insisting on special cases for "returns a thing" and "doesn't".

Example: I hold a thing of type `T` and want to let you call a function on it. I can write this generically as

    pub trait WithMut<T> {
      fn with_mut<R, F: Fn(&mut T)->R>(&mut self, func: F) -> R;
    }
and now with one implementation I can deal both with functions that return meaningful values, and "computations" that do some work but return nothing (other than `()`).
No it isn’t. In practice it’s extremely obvious when it is happening. And if you mess up and add a semi colon accidentally then the type checker will catch it.
I wish there was times that HN supported Quadratic Voting[0] so that I could more (but costly) up votes to a really sane and pertinent comment.

[0] http://ericposner.com/quadratic-voting/

Have you tried writing Rust? I have and I think this feature is great.

I upvoted you for your link, but actually the argument that it would be good because people who care more will make a better decision than those who don't does not completely convince me. Someone could care a lot about something but still have the wrong idea about it.

Thanks for the link, I started reading the paper. I love this:

Groups frequently make collective decisions through majority rule. Legislators pass bills by majority; shareholders make most corporate decisions by (share-weighted) majority rule, as do directors; clubs, university faculties, and civic associations typically use majority rule as well. The reason that they do so is not entirely clear. (Emphasis mine).

>The reason that they do so is not entirely clear.

Not clear? It's almost too clear as to be tautological.

They do because they (a) think all members should have equal say, (b) most members in the group want X to be done.

Unless we're talking about submitting to force or listening to expertise, why would many people wanting to do something, let fewer people tell them what to do instead?

Heck, if it comes to fighting for what's to be done (the most effective but primitive form of getting a decision), the majority could beat up the minority and have its way anyway.

Since we're going off-topic about QV here: am I correct in my understanding that you can _buy_ votes there? Because the obvious problem (because I'm probably missing something) with that would be that money is not as costly for some as it is for others? In other words, it'd lead to tyranny of the wealthy?
(from a cursory read) You can buy votes, but they become increasingly costly. Also, the payments are redistributed out among the population, so if you spend 1B to buy 31.6K votes, that 1B gets handed to the population at large who, if larger in number, can more efficiently re-spend it voting you down.

What I imagine QV does is find the point at which participants who don't care so much would rather pocket the funds and walk away, rather than spend it on voting.

If the ballot measure is "Eat Vinnl", you might want to spend a lot to vote it down, but it might not take much to convince the others not to spend it back at you (and you all eat berries instead). If the ballot measure is "Vinnl eats everyone else", you won't be able to spend enough that everyone else can't just spend it back at you, more efficiently.

Edit: one important difference here is that unless the GP is actually going to pony up real money, something of value to those they inconvenience with their (imo silly) opinion, it doesn't make much sense.

So it's a method of exchanging influence for money for poor people, and money for influence for rich people? Still doesn't sound that great...

Anyway, I see it's been submitted separately :) https://news.ycombinator.com/item?id=15206291

Interesting idea, but what if I stead of buying them, we could spend our accumulated points to emphasize ideas.
I've never heard about quadratic voting before. This is very interesting!
In practice it's not so bad, because your program won't compile if you've missed returning something in any branch, or if you've returned the wrong thing.
I was thinking the same before actually using rust. Turns out it surprisingly awesome given how rust treats statements and expressions.

it just makes obvious that "result of something" and "control flow back to caller" are very different things.

Don't sweat it, your compiler will point it out and it's fairly ingrained to functional programmers that the last line of function is its return value anyway
Oh definitely, implicit returns are awesome. I just commented on the fact that a semicolon supresses them.
How do you feel about the ! operator?
I won't even get started. I see no reason why a modern language would use it in preference to "not" (like Python).
By your logic, you should also hate the "+" and "-" operators – they're just as easy to confuse as ";" and "", completely change the semantics, and the type checker won't even catch your mistake!