3 ms·
> I want to write BalancedI8 So, you want an integer, but one value sacrificed to denote not-a-number? Is this what "niche" means? So that with these, you can
by sampo 2y ago
> I want to write BalancedI8
So, you want an integer, but one value sacrificed to denote not-a-number? Is this what "niche" means?
So that with these, you can have Option[integer8, None], an option type that either contains a -127 to +127 8bit integer or contains the empty value, and still consumes only 8 bits of memory? Or are there other uses for this?
And Rust already has this, and with the memory optimization, but for some reason only the version where they sacrificed the value 0.
https://doc.rust-lang.org/std/num/type.NonZeroI8.html https://doc.rust-lang.org/std/num/type.NonZeroI8.html
- Joker_vD 2y agoThe main use is not having to deal with INT_MIN, the two chief problems of which is that you a) you can't sensibly abs() it, b) most people tend to forget about point a). This problem in my experiences most commonly arises in naive implementations of itoa/etc. which tend to assume that they can just call abs() and concentrate on the positive half-range signed integers. Nope, you can't do this, not all negative integers have a positive counterpart.
- deleted 2y ago[deleted]
- tialaramex 2y agoYes, I want to be able to make such types myself. You're correct that Rust provides NonZeroI8, which in fact I called out in my text. If you look at the source, you'll see that the Rust standard library is allowed to make this type but you can't in stable Rust, [rustc_layout_scalar_valid_range_start(1)] means, "Hey, Rust compiler, I promise it's fine to just assume I never have this value: 0". You absolutely could write BalancedI8.... if you're the Rust standard library. Unfortunately you aren't allowed to do that in your own stable Rust software because it needs these compiler internals. There were discussions about stabilising this idea, and they were knocked back because if you do that you're basically stuck with it forever. One day in the future NonZeroI8 could "just" be a Pattern Type, like the ones you can make at home, but today there are no Pattern Types and NonZeroI8 needs compiler magic. There are other Rust core types which you could make yourself, IPv4Addr for example is just a 32-bit value, you could make your own, but yours wouldn't be on everybody's Rust system. Option<&T> is just a sum type over &T and None, you genuinely could make your own, call it Maybe<&T> and it would work exactly the same - same optimisations even, although not all the compiler diagnostic messages would be as good if you use it wrong I think. But today NonZeroI8 isn't like them, it actually needs a sprinkle of compiler magic.
- edflsafoiewq 2y agoThey're sort of used in graphics APIs. When a value in [-1.0, 1.0] is quantized to an i8, the result is a BalancedI8: -1.0 maps to -127, 1.0 to 127, and -128 is unused; if -128 is used in the dequantizer, it is treated the same as -127. This replaced the old scheme where -1.0 mapped to -128 in which 0.0 was unrepresentable. The value of encoding this case in the type system seems minimal to me though.
- ziml77 2y agoThe reason to encode it in the type system is it allows for optimization. Option<NonZeroI8> uses a single byte because it knows 0 is available to represent the None state. Option<BalancedI8> could do the same thing with -128 representing None.