We can use match to do pattern matching:
let name = match color_code {
0 => "red",
1 => "blue",
2 => "green",
_ => "unknown",
};
The RHS of the `=>` has to be an expression, since we're assigning it to a variable. Here, you should already see one "useful" side-effect of what you're calling "syntactic elements" (I'd perhaps call them "block statements", which I think is closer to the spirit of what you're saying.) The whole `match … {}` in the example above here is an expression (we assign the evaluation of it to a variable).
> What practical value is it to users to allow "return " to itself be an expression?
Now, what if I need to return an error?
let name = match color_code {
0 => "red",
1 => "blue",
2 => "green",
_ => return Err("unknown color"),
};
The expression arms need to be the same type (or what is the type of `name`?). So now the type of the last branch is !. (Which as you hopefully learned from TFA, coerces to any type, here, to &str.)
There's more ways this "block statements are actually expressions" is useful. The need not be a ternary operator / keyword (like C, C++, Python, JS, etc.):
let x = if cond { a } else { b };
In fact, if you're familiar with JavaScript, there I
want this pattern, but it is not to be had:
const x; // but x's value will depend on a computation:
// This is illegal.
if(foo) {
x = 3;
} else {
x = 4;
}
// It's doable, but ugly:
const x = (function() { if(foo) { return 3; } else { return 4; }})();
// (Yes, you can do this example with a ternary.
// Imagine the if branches are a bit more complicated than a ternary,
// e.g., like 2 statements.)
Similarly, loops can return a value, and that's a useful pattern sometimes:
let x = loop {
// e.g., find a value in a datastructure. Compute something. Etc.
if all_done {
break result;
}
};
And blocks:
let x = {
// compute x; intermediate variables are properly scoped
// & cleaned up at block close.
//
// There's also a slight visual benefit of "here we compute x" is
// pretty clearly denoted.
};
>
Even if you disagree with this argument, this design decision has resulted in all these weird/confusing but absolutely useless code examplesI think one can cook up weird code examples in any language.