I don't understand the one with dont(). Why does i.get() end up false at the end? Shouldn't it be true after having been set by dont()?
Weird Expressions in Rust
51–60 of 155 posts
Re: Weird Expressions in Rust
#52Honestly I'm surprised how not weird these are. Way less WTFy than Javascript, PHP, C or C++.
you still can create some more confusing things by idk. overloading some operators (but luckily not `=` and similar crazy C++ things) adding recursive macros and maybe combining it with lifetime variance and coercion edge cases, maybe sprinkle in some arcane `#[]` annotations and people with be very confused, more so then in the article
Re: Weird Expressions in Rust
#53they exist because whole language built to treat expressions as firstclass citizens : blocks, ifs, matches, even macros as expressions that return values. so once you internalize that, all these weirdo one liners are artifacts. just artifact of a system where expressions compose infinitely. the syntax tree runs deeper than most people's habbits allow. you hit that depth and brain says this is wrong but compiler's all…
Hmm my read is this is a slight overstatement - Rust was always built with the idea of expressions as first class citizens, but practicality and performance requires expression-breaking keywords like “return” which don’t fit neatly in an ML-ish language and have a few plain old hacks associated with implementing them (not “hack” as in lacking robustness; I mean theoretically/formally inelegant). Likewise there’s some…
There are very few statements: https://doc.rust-lang.org/stable/reference/statements.html
and a lot of expressions: https://doc.rust-lang.org/stable/reference/expressions.html
Re: Weird Expressions in Rust
#54Earlier quoted context omitted.
If a language that claims to be security focused is easily able to express constructs that human minds find barely comprehensible, or worse, then this is itself arguably a security issue: it's impossible to check the correctness of logic that is incomprehensible.
What's the threat model? If you're reviewing untrusted or security-critical code and it's incomprehensible, for any reason, then it's a reject. Syntax alone can't stop sufficiently determined fools. Lisp has famously simple syntax, but can easily be written in an incomprehensible way. Assembly languages have very restrictive syntax, but that doesn't make them easy to comprehend. Rust already has a pretty strong type…
Re: Weird Expressions in Rust
#55Earlier quoted context omitted.
What's the joke exactly? English is not my native language.
https://www.basicfun.com/lincoln-logs/ This would be something the Boomer generation grew up with, and I think maybe the previous generation too. They're still around but they've certainly faded; they used to be Lego-level popular kids toys back then. They are named after President Lincoln, but only as a marketing tactic to use some of his reputation, there's no real connection. I would imagine even some native Engli…
Re: Weird Expressions in Rust
#56Earlier quoted context omitted.
https://www.basicfun.com/lincoln-logs/ This would be something the Boomer generation grew up with, and I think maybe the previous generation too. They're still around but they've certainly faded; they used to be Lego-level popular kids toys back then. They are named after President Lincoln, but only as a marketing tactic to use some of his reputation, there's no real connection. I would imagine even some native Engli…
> They were named after President Lincoln, but only as a marketing tactic > there's no real connection Funny--I always thought it was meant to be a pun on linkin', as in you're linkin' the logs together because they have those slots that fit precisely together on the ends.
Re: Weird Expressions in Rust
#57Earlier quoted context omitted.
That sounds superficially reasonable to me and I'm all for regularity in programming language semantics but on thinking about it further, I actually think it's a design flaw. It makes no more sense to me for "return " to have a type than it does to make "if " or "break" or "{" or any other keyword to have a type. These are syntactic elements. Rust's type system is clearly inspired by Hindley-Milner and most languages…
The issue with `return expr` not having a type is that you lose the ability to write something like let y = match option { Some(x) => x, None => return Err("whoops!"), }; Without a type, the None branch loses the ability to unify with the Some branch. Now you could say that Rust should just only require branches’ types to unify when all of them have a type, but the ! never type accomplishes that goal just fine.
In your particular example, let's put your example into a context. Is
fn foo(option: Option) -> i32 {
let y = match option { Some(x) => x, None => return Err("whoops!"), };
return 1;
}
well typed? It should be if we are to believe that "return " is an expression of type () - but, naturally, it causes a compilation error because the compiler specifically treats "return " unlike other expressions. So there is no improvement in regularity, while it admits all sorts of incomprehensible "puzzlers".I don't see why you'd lose this ability if you removed the claim that "return " is itself an expression. Most/many languages have mechanisms to allow expressions to affect flow control - e.g. with exceptions, yield, etc. - which do not these constructs (for example "throw x") to have a type.
Rust could just as easily supported the syntax you use above without making "return " a tapeable expression.
Re: Weird Expressions in Rust
#58if you extend it to the most cursed ~6 lines of code, you really can obfuscate what you're doing in a way that's fiendishly hard to debug.
Re: Weird Expressions in Rust
#59they exist because whole language built to treat expressions as firstclass citizens : blocks, ifs, matches, even macros as expressions that return values. so once you internalize that, all these weirdo one liners are artifacts. just artifact of a system where expressions compose infinitely. the syntax tree runs deeper than most people's habbits allow. you hit that depth and brain says this is wrong but compiler's all…
Hmm my read is this is a slight overstatement - Rust was always built with the idea of expressions as first class citizens, but practicality and performance requires expression-breaking keywords like “return” which don’t fit neatly in an ML-ish language and have a few plain old hacks associated with implementing them (not “hack” as in lacking robustness; I mean theoretically/formally inelegant). Likewise there’s some…
The main difference from other MLs is the lack of higher kinded types, so it’s difficult to express things like Functor, Monad, Arrow, etc
Re: Weird Expressions in Rust
#60Earlier quoted context omitted.
The issue with `return expr` not having a type is that you lose the ability to write something like let y = match option { Some(x) => x, None => return Err("whoops!"), }; Without a type, the None branch loses the ability to unify with the Some branch. Now you could say that Rust should just only require branches’ types to unify when all of them have a type, but the ! never type accomplishes that goal just fine.
I'm responding here because so many replies are making the same point. In your particular example, let's put your example into a context. Is fn foo(option: Option ) -> i32 { let y = match option { Some(x) => x, None => return Err("whoops!"), }; return 1; } well typed? It should be if we are to believe that "return " is an expression of type () - but, naturally, it causes a compilation error because the compiler speci…
It's not, but not due to the return, it's because you're trying to return a Result from a function that returns an i32. This works:
fn foo(option: Option) -> Result {
let y = match option { Some(x) => x, None => return Err("whoops!"), };
return Ok(1);
}
> It should be if we are to believe that "return " is an expression of type ()It is not, it is an expression of type !. This type unifies with every other type, so the overall type of y is i32. return is not treated in a special way.
> if you removed the claim that "return " is itself an expression
This code would no longer work, because blocks that end in an expression evaluate to (), and so you would get the divergent, not well typed error, because one arm is i32 and the other is ().