2 ms·
I don't think an integer NaN would be a good idea. People's intuition around the existing float NaNs is not good. I want to make user defined types like Balanc
by tialaramex 3y ago
I don't think an integer NaN would be a good idea. People's intuition around the existing float NaNs is not good.
I want to make user defined types like BalancedI32 (32bit signed integer but the magnitude of MAX and MIN are the same) possible in Rust. Today the stdlib is allowed to make NonZeroI32 which as its name suggests lacks zero but you can't make such types yourself except via wrapping these NonZero types with xor or similar.
(In nightly Rust you can just break the rules and do the same thing the stdlib does, but there's no obligation to keep that working and it will never be stabilized)
Because of the Guaranteed Niche Optimisation this means Option<BalancedI32> would have identical size to i32. So you get the same practicality as a normal signed integer with a sentinel value, but the same programming ergonomics as an expensive high level type.
- lifthrasiir 3y ago> People's intuition around the existing float NaNs is not good. I think that, if NaN was defined to be an unconditional trap but can be deferred for efficiency, then it could have worked much better. NaN surprises people because it was exposed in the first place, while it should really have been hidden behind the scene (because the presence of NaN means you are already wrong somewhere, and you are expected to be notified about that fact). In terms of Rust, say, every f32 operation could have returned `Result<f32, FloatError>` (mostly likely to be aliased though) that has the exactly same layout as the current f32. The current split between qNaN and sNaN (among others) is unnecessarily complex with little benefit.
- anonymoushn 3y agoHas Rust seriously committed to never stabilizing the ability for users to create types like the builtin string type? Wow.
- tialaramex 3y agoHuh? I think you might have skimmed what I wrote a bit too fast and didn't end up comprehending most of it. Some Rust types have niches, bit patterns which the type doesn't use. For example booleans take up a whole byte, but only need two bit patterns, leaving 254 unused. Today there is no stable way to conjure into existence a type with a new niche of your choosing. The example I gave was BalancedI32, a type which is exactly like i32 except that it doesn't use the most negative value. The most negative value of integers in a two's complement system is a weird outlier, so in many ways this is nicer to work with, but the niche also allows such a type to take advantage of the Guaranteed Niche Optimisation. Rust's String type is basically just a Vec<u8> with extra promises about the bytes (they're guaranteed to be a UTF-8 string) and there's nothing special about it, you can make your own and several people have. You can even use an existing niche to do clever things, as CompactString does.
- anonymoushn 3y agoI agree I've misunderstood things. I thought that the general class of "some bytes that are guaranteed to only contain certain bit patterns" was addressed by a single feature, but actually there's a single feature that addresses this for only primitives and types similar to primitives in some sense. The builtin string type is doing some unrelated thing where it has a thing and it assumes that the thing will contain only a strict subset of the possible bit patterns of the thing or you get nasal demons, and user code is free to do that, but doing that is unrelated to niche optimizations. Thanks.