Live data from Hacker News

Never patterns, exhaustive matching, and uninhabited types in Rust

smallcultfollowing.com

1–10 of 83 posts

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#2
> This post describes the idea of a “never pattern” (written !) that matches against the ! type or any other “empty enum” type. It also describes an auto-never transformation that inserts such patterns into matches. As a result – in the desugared case, at least – we no longer use the absence of a match arm to designate matches against uninhabited types.

> Explicit ! patterns make it easier to define what data a match will access. They also give us a way to use lints to help bridge the needs of safe and unsafe code: we can encourage unsafe code to write explicit ! patterns where they might help document subtle points of the semantics, without imposing that burden on safe code.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#3
Can someone explain why you'd want uninhabited types?

> if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type.

I don't see the reason behind returning a Result if there is no error to return. Why not just return a String?

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#4
post #3

Can someone explain why you'd want uninhabited types? > if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type. I don't see the reason behind returning a Result if there is no error to return. Why not just return a String?

Perhaps you’re making use of a parametric type provided by a library, and you don’t have control over the structure except by filling in type parameters.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#5
post #3

Can someone explain why you'd want uninhabited types? > if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type. I don't see the reason behind returning a Result if there is no error to return. Why not just return a String?

When you implement a generic trait that is designed to handle errors but your specific case is infallible then it is helpful to indicate that the error case can never occur. Marking that as uninhabited makes it easier for downstream consumers to just eliminate all code related to error handling for that concrete type.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#6
post #3

Can someone explain why you'd want uninhabited types? > if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type. I don't see the reason behind returning a Result if there is no error to return. Why not just return a String?

I've used `enum Void { }` as a placeholder for opaque FFI managed types that I pass between APIs but never inspect myself. Like Windows handles (`*const Void`) or data structures that are queried using an API rather than directly.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#7
Alright this is going to be a dumb question but...

Every time I start a new personal project I say 'oh neat I can use Rust!' N hours later (where N is a large number) I realize Go is about as fast, much easier and more readable syntax, and so I use Go if I want something that isn't Node. I'm a web developer so maybe Rust just isn't useful for that, but is Rust purely a systems level language for making super low level stuff? Forgive my ignorance, but what do people actually use it for where it outshines other languages?

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#8

Alright this is going to be a dumb question but... Every time I start a new personal project I say 'oh neat I can use Rust!' N hours later (where N is a large number) I realize Go is about as fast, much easier and more readable syntax, and so I use Go if I want something that isn't Node. I'm a web developer so maybe Rust just isn't useful for that, but is Rust purely a systems level language for making super low leve…

Type safety and zero cost abstractions are the two main draws.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#9
post #3

Can someone explain why you'd want uninhabited types? > if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type. I don't see the reason behind returning a Result if there is no error to return. Why not just return a String?

A string is the worst thing to return because it’s huge. Most people return () instead which is zero sized.

However when returning ! the compiler can optimize the entire error handling away.

Re: Never patterns, exhaustive matching, and uninhabited types in Rust

#10

Alright this is going to be a dumb question but... Every time I start a new personal project I say 'oh neat I can use Rust!' N hours later (where N is a large number) I realize Go is about as fast, much easier and more readable syntax, and so I use Go if I want something that isn't Node. I'm a web developer so maybe Rust just isn't useful for that, but is Rust purely a systems level language for making super low leve…

I wrote a fair bit of go at my old job and I just finished a small internal rust utility at my current job. i liked go at first but then got completely fed up with the error handling, the module/folder nonsense, having to define the same function over and over for different primitive types when it came up, and nil. so I picked up rust. it's miles better. the syntax is not as bad you imagine - my utility is about 1000 lines and there are no lifetime parameters anywhere. the functional stuff is clean (closures, iterators, match). there are real enums (none of that iota nonsense) which as a "mature" developer have become integral to the design of any system for me. writing macros is easy (basically just like code gen in go). the borrow checker isn't that hard to satisfy - only one thing was a head scratcher and #rust-beginner helped me out there. cargo is great and so is RLS. there are a surprisingly large number of libraries given how young the language is (fewer than go for sure but enough that I didn't have to implement anything tedious myself). I mean it's just an all around pleasant experience and you're guaranteed to be writing performant (zero cost abstractions) safe code. how can you beat that? the only thing I miss from go are goroutines and the lightning fast compiler (but the rust compiler is plenty fast for how much it does). so I will probably use rust for everything other than what's fit for a python script from now on.
Post reply on HN