[HN Gopher] Tell HN: Rust Is Complex
       ___________________________________________________________________
        
       Tell HN: Rust Is Complex
        
       I'll preface this by saying I like Rust, and I've found myself
       coding more in Rust the last two years than anything else. But
       Rustaceans kind of like to laugh at Go, because it's not as
       expressive or elegant a language by comparison. That's mostly true,
       think of how nicely Option types, enums, and iterators work in Rust
       compared to Go. However, Go is simple and deeply pragmatic. There
       is an underrated value in that. Some parts of Rust are starting to
       remind me of the horror I ran from with C++. Look at this:  Update:
       It is possible to abuse existing CoerceUnsized implementations on
       stable. See #85099 (although I created that issue before reading
       any of this issue and its IRLO thread, so don't expect any
       syntactic similarity to the unsoundness examples of this issue).
       The type Pin<&LocalType> implements Deref<Target = LocalType> but
       it doesn't implement DerefMut. The types Pin and & are
       #[fundamental] so that an impl DerefMut for Pin<&LocalType>> is
       possible. You can use LocalType == SomeLocalStruct or LocalType ==
       dyn LocalTrait and you can coerce Pin<Pin<&SomeLocalStruct>> into
       Pin<Pin<&dyn LocalTrait>>. (Indeed, two layers of Pin!!) This
       allows creating a pair of "smart pointers that implement
       CoerceUnsized but have strange behavior" on stable
       (Pin<&SomeLocalStruct> and Pin<&dyn LocalTrait> become the smart
       pointers with "strange behavior" and they already implement
       CoerceUnsized).  More concretely: Since Pin<&dyn LocalTrait>:
       Deref<dyn LocalTrait>, a "strange behavior" DerefMut implementation
       of Pin<&dyn LocalTrait> can be used to dereference an underlying
       Pin<&SomeLocalStruct> into, effectively, a target type (wrapped in
       the trait object) that's different from SomeLocalStruct. The struct
       SomeLocalStruct might always be Unpin while the different type
       behind the &mut dyn LocalTrait returned by DerefMut can be !Unpin.
       Having SomeLocalStruct: Unpin allows for easy creation of the
       Pin<Pin<&SomeLocalStruct>> which coerces into Pin<Pin<&dyn
       LocalTrait>> even though Pin<&dyn LocalTrait>::Target: !Unpin (and
       even the actual Target type inside of the trait object being
       returned by the DerefMut can be !Unpin).  Methods on LocalTrait can
       be used both to make the DerefMut implementation possible and to
       convert the Pin<&mut dyn LocalTrait> (from a Pin::as_mut call on
       &mut Pin<Pin<&dyn LocalTrait>>) back into a pinned mutable referene
       to the concrete "type behind the &mut dyn LocalTrait returned by
       DerefMut".  From: https://github.com/rust-
       lang/rust/issues/68015#issuecomment-835786438  Where's that
       elegance now? I still maintain that I'd rather use Go when the
       problem domain allows for it (e.g. can use a garbage collector,
       don't need fast interoperability with C, don't need maximum
       performance.)
        
       Author : eloff
       Score  : 8 points
       Date   : 2022-11-13 21:22 UTC (1 hours ago)
        
       | RcouF1uZ4gsC wrote:
       | Question: How much of Rust's type system complexity is due to
       | async? It seems Pin is mostly related to async and the official
       | examples for GAT are for async.
       | 
       | Given the complexities of async and how other alternatives such a
       | Java Loom's virtual threads, in about 10 years I am not sure that
       | we won't see Rust going all in on async as a mistake.
        
       | throwawaymaths wrote:
       | The problem with go is not it's simplicity, it's it's
       | _inconsistency_. As a small-minded programmer my hobgoblin is
       | tripping over having to remember that X works this way but not Y,
       | which looks vaguely like x.
       | 
       | It feels like the designers of go tripped over themselves to make
       | things simple _for some definition of simple_ and then ran into
       | some feature they wanted and then just bolted the feature on
       | without thinking about whether simplicity /consistency tradeoffs
       | were a thing.
        
         | 2fast4you wrote:
         | Do you have more examples? I'll admit that Go is full of weird
         | quirks, but nothing feels bolted on. Generics were agonized
         | over for so long because they had to fit it within the existing
         | language
        
       ___________________________________________________________________
       (page generated 2022-11-13 23:01 UTC)