Earlier quoted context omitted.
It's simply that Rust has higher standards for breaking changes than "probably not in wide use." In other words, that someone could have had `let union =`... somewhere was a reason to make it contextual. https://rust-lang.github.io/rfcs/1444-union.html#contextual-...
Ooooooh, I see my confusion now. My brain switched off and I got enums and unions confused. I was like, wait, hasn't Rust had them since day one? I was thinking of `enum`, not `union`. My bad.
Weird Expressions in Rust
111–120 of 155 posts
Re: Weird Expressions in Rust
#112Earlier 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…
e: T is well typed _if_ the end result of e would be of type T
(end result being hand-wave-y)
It's not a guarantee that e is a value of a certain type, but a guarantee that if e is a value in the first place, then it will be a certain type. You sidestep having to prove the halting nature of e.
This leaves a nice spot for computation that doesn't complete!
let y = return 1
f(y)
y could be any type, and it's well typed, because you're never in a secnario where f(y) will be provided a value of the wrong type.Well-typed-ness, by my understanding in more complex type system, is not a guarantee of control flow, but a guarantee that _if_ we evaluate some expression, then it will be fine.
And so... you can put `!` as a type in your system, treat return as an expression, and have a simpler semantic model, without really losing anything. Less moving parts, etc.... that's my read of it anyways.
Re: Weird Expressions in Rust
#113Earlier quoted context omitted.
its not just that some things you would usually think are control flow are expressions, its also that there are unusual rules around coercing the `noreturn` type.
The only "unusual" rule here is that Rust offers the zero type addition, but does not provide the (much more complicated) other type additions So Rust does have: String + ! = String But Rust doesn't have: String + i32 = Either Note that the never type ! isn't special here, Rust will also cheerfully: String + Infallible = String or if you were to define your own empty type like so: enum MyEmptyType {} // MyEmptyType h…
Re: Weird Expressions in Rust
#114this is why I like Go
I wonder, what's the "weirdest" expression in Go? Here's one: type Foo struct{} func (Foo) Bar() { println("weird...") } func main() { ([...]func(){^^len(` `): (&Foo{}).Bar})[cap(append([]any(nil),1,2,3))]() }
Re: Weird Expressions in Rust
#115Earlier quoted context omitted.
I do think we're speaking past each other. I don't fully agree with your "CS sense of the term," as Rust does have a semantically meaningful type: !. This is all pretty bog-standard stuff. Rust isn't doing anything weird or novel here.
I do wonder how many languages have the "never returns" type explicitly available. Typescript and Rust.... Haskell has bottom but I wonder semantically how much space there is between bottom and "never return". Obviously laziness makes things weird. This is what I find interesting in this generation of languages though. Any C programmer understands the notion of an infinite loop, and the value of conditional expressi…
https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-nothin...
As you can never get a value of type nothing, it can coerce into anything, just like rust's ! or () or typescripts never.
Re: Weird Expressions in Rust
#116this is why I like Go
Re: Weird Expressions in Rust
#117Earlier 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…
... in your country I assume. I've never heard of these, but from the looks of it, they look like an American version of Playmobil or Fisher Price.
Re: Weird Expressions in Rust
#118This post is missing my favorite one! fn evil_lincoln() { let _evil = println!("lincoln"); } What's weird about this? To understand what evil_lincoln is doing, you have to understand very old Rust. Here's the commit that introduced it: https://github.com/rust-lang/rust/commit/664b0ad3fcead4fe4d2... fn evil_lincoln() { let evil log was a keyword to print stuff to the screen. Hence the joke, https://en.wikipedia.org/wi…
Re: Weird Expressions in Rust
#119Earlier quoted context omitted.
Steve, I know you're an authority on the language but you've dismissed the point being made here without engaging with it. Return is a statement in the minds of most programmers, but an expression in the language. That was a very pragmatic decision that required an unintuitive implementation. As a result, we've got this post full of code that is valid to the compiler but doesn't make a lick of sense to most programme…
We've been going down this road for a long time now. E.g. "throw" is a (void-typed) expression in C++ already for similar reasons, although it doesn't go far enough without a proper bottom type. C# took it further and added the type so that you can write things like e.g. `x = y ?? throw new Error(...)`. There's no obvious reason why "return" should be conceptually different. A better question at this point, arguably,…
In fact, I recently ran into the finding that you can't use it with logical operators either: `return myBool && throw...` doesn't work. I assume that's because && can be used with many types even if the first operand is a bool, but the compiler error message doesn't explain that, it just says throw is an invalid token here, and if you parenthesize it, it says a throw expression can't be used in this context. I was very surprised by this seemingly arbitrary limitation.
Re: Weird Expressions in Rust
#120Earlier quoted context omitted.
I do wonder how many languages have the "never returns" type explicitly available. Typescript and Rust.... Haskell has bottom but I wonder semantically how much space there is between bottom and "never return". Obviously laziness makes things weird. This is what I find interesting in this generation of languages though. Any C programmer understands the notion of an infinite loop, and the value of conditional expressi…
Kotlin also has this type, it's called "Nothing". https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-nothin... As you can never get a value of type nothing, it can coerce into anything, just like rust's ! or () or typescripts never.
[1]: https://leanprover-community.github.io/mathlib4_docs/Init/Pr...