6 ms·
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 req
by AIPedant 1y ago
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 stuff (u8) which is a simple syntax quirk. But a lot of these return/etc oddities are because Rust is ultimately an imperative language with strong influence from functional programming.
- efnx 1y agoI’ve found rust to be an ML in C’s clothing. 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
- steveklabnik 1y agoreturn is an expression in Rust, and it fits in well. There are very few statements: https://doc.rust-lang.org/stable/reference/statements.html https://doc.rust-lang.org/stable/reference/statements.html and a lot of expressions: https://doc.rust-lang.org/stable/reference/expressions.html https://doc.rust-lang.org/stable/reference/expressions.html
- AIPedant 1y agoWe're speaking past each other since there's "expression" as defined in the Rust specification vs "expression" as in ordinary computer science, and Rust's use of return is certainly not an expression in the latter sense. It is shoehorned into being called an expression but it has no semantically meaningful type, it is an effect. A type is (carefully but somewhat arbitrarily) assigned to it, which is why some of those examples involving "return" are particularly goofy. It is not material for most programs since it only comes up with intentional misuse of the keyword. But "return" does not make sense in functional languages with true first-class expressions - functions don't return values, they get evaluated and the frame destruction / etc are all abstracted away. It makes sense in Rust because expressions in the CS sense of the term are ultimately not first class.
- steveklabnik 1y agoI 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.
- rtpg 1y agoI 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 expressions like ternary ops. But now languages are realizing that when you start treating more and more things as expressions, you really want to start giving names to things that you wouldn't name in the past.
- kuschku 1y agoKotlin also has this type, it's called "Nothing". https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-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.
- nialv7 1y agoI recently realized (by playing with Lean) that coercing of "!" is because of the principle of explosion [1]. Basically propositions are types in Lean, and proofs are instances of those types. A proposition that is false doesn't have any instances, so they are like "!". Principle of explosion says ∀ P, False -> P, which is exactly the type signature for "!" coercing. [1]: https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html#False.elim https://leanprover-community.github.io/mathlib4_docs/Init/Pr...
- valenterry 1y ago
- missinglugnut 1y agoSteve, 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 programmers reading it.
- steveklabnik 1y ago> Return is a statement in the minds of most programmers I would take issue with this, sure, for a lot of people, they may be bringing assumptions over from languages where assignment is a statement. That doesn't make them correct. > required an unintuitive implementation To some people, sure. To others, it is not unintuitive. It's very regular, and people who get used to "everything is an expression" languages tend to prefer it, I've found.
- hansvm 1y ago> people who get used to "everything is an expression" languages tend to prefer it, I've found I.e., if we bias our sample to the data points proving our point then our point is proven. It's like that quip about how every car insurance company can simultaneously claim "people who switched saved hundreds of dollars in average." I also like "everything is an expression" languages, but I don't think that's a fantastic argument.
- saghm 1y agoThe original claim that the was responding to in this thread was that `return` as an expression didn't fit in well with Rust, and he said that it did. He also cited how far more things in Rust are expressions than statements, so it stands to reason that people who program in Rust are familiar with those styles of language. It sounds like you're arguing that it makes more sense to judge whether return makes sense as an expression in Rust based on the expectations of people who aren't as familiar with expression-based languages (and therefore aren't super familiar in Rust), which doesn't make a ton of sense to me.
- GrantMoyer 1y agoHaskell has `bottom`[1] (see also [2]), which acts like Rust's `return` from a type checking perspective. I wouldn't call using a uninhabited type for the type of a return expression theoretically inelegant. On the contrary, I find it quite pleasing. [1]: https://wiki.haskell.org/Bottom https://wiki.haskell.org/Bottom [2]: https://en.wikipedia.org/wiki/Bottom_type https://en.wikipedia.org/wiki/Bottom_type
- saghm 1y agoI'm confused about your parenthetical about "u8". What does the name of the unsigned 8-bit integer type have to do with whether the language is imperative?