
Never patterns, exhaustive matching, and uninhabited types in Rust - fanf2
http://smallcultfollowing.com/babysteps/blog/2018/08/13/never-patterns-exhaustive-matching-and-uninhabited-types-oh-my/
======
vultour
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<String, Err> if there is no
error to return. Why not just return a String?

~~~
the_mitsuhiko
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.

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

I think what they're asking is "if you're returning a Result<String, Err>" but
you're making the Err an unhinabitated type (so can't ever have an error) why
not just return a String in the first place?

~~~
the_mitsuhiko
Because there are generic APIs that return results as part of the contract. A
good example is FromStr.

------
patientplatypus
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?

~~~
dom96
I actually often wonder why so many web developers are drawn to Rust.
Satisfying a borrow checker just doesn't seem like a worthwhile task when
writing web apps. Are there things about Go that you feel are bad enough to
warrant a switch to Rust?

~~~
mpartel
Performance is not the only benefit. You also get freedom from data races, and
(arguably) the borrow checker imposes structure that makes the program easier
to read and reason about, because it's clearer who "owns" (and can mutate)
what, and what is shared.

I've missed this property when writing Java and JS even before Rust was a
thing, and Go has felt the same.

~~~
Thiez
Exactly, the clear ownership in Rust allows you to skip the defensive copying
that so often happens in Java. Of course you get this property in most
languages that do not use garbage collection, but I few restrict mutable
aliasing.

------
codesections
> 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.

