5 ms·
Can anyone brief what NonZero even is.. or rather, it's application? From the sounds of it, it's literally just a u8 (or w/e) that can't be zero.. but what use
by asdkhadsj 8y ago
Can anyone brief what NonZero even is.. or rather, it's application? From the sounds of it, it's literally just a u8 (or w/e) that can't be zero.. but what use case does that have?
- steveklabnik 8y agoLet's take an enum, like Option: enum Option<T> { Some(T), None, } Under the hood, this is a "tagged union"; Rust has to have enough space for the T, but also for a tag, to say which variant is the current one. If T is a NonZero type, then we know that zero is never a valid value. That means that instead, Rust can use the zero value to mean the None case, and any other value to be the Some case, completely eliminating the extra tag, and reducing the size of the Option. This is a good example of a "zero-cost abstraction"; an Option in this case has absolutely no extra associated overhead at runtime. Note that these optimizations aren't specialized for Option; they apply to anything that has this kind of shape.
- asdkhadsj 8y agoThat's actually really cool! Thanks for the explanation
- steveklabnik 8y agoNo problem!
- monocasa 8y agoIs NonZero* special cased by the language? If for instance, I had a preexisting binary interface where 0 through (2^n - 2) is valid, but all bits set is the invalid case, can I explain that to the compiler as well?
- steveklabnik 8y agoYes, it is. The case you're talking about is pertinent to the above discussion on why it's NonZero* vs NonZero<T>; you cannot currently inform the compiler in your case.
- mrec 8y agoExcellent explanation. Have you considered writing some sort of book? :P
- steveklabnik 8y agoHeh, thank you. There's too many books that I want to write...
- slavik81 8y agoI've occasionally thought that if I were to design my own language, it would be nice to try using INT_MIN as the invalid value that marks None. I've never actually used the extra negative value you get from twos-compliment, so giving it up in exchange for a smaller Option<T> seems like an excellent trade. Though, I wonder if that might have some complications for stuff like overflow checking. I suppose you could always wrap NonZero with an accessor that adds 1 if negative to achieve the same result, though that might be too much overhead to be worth it.
- eptcyka 8y agoWhilst a great response, I think the practical implication of being able to ensure you never divide by zero did not shine through :)
- bryanlarsen 8y agoIt's also useful for divisors.