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.
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
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.
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.
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.
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
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!
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:
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:
or: 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.