zlacker

[return to "Nimony (Nim 3.0) Design Principles"]
1. esafak+uTb[view] [source] 2025-12-05 14:08:33
>>andsoi+(OP)
> "Modern" languages try to avoid exceptions by using sum types and pattern matching plus lots of sugar to make this bearable. I personally dislike both exceptions and its emulation via sum types. ... I personally prefer to make the error state part of the objects: Streams can be in an error state, floats can be NaN and integers should be low(int) if they are invalid.

Special values like NaN are half-assed sum types. The latter give you compiler guarantees.

◧◩
2. saghm+pWc[view] [source] 2025-12-05 18:48:38
>>esafak+uTb
Yeah, I'm not sure I've ever seen NaN called or as an example to be emulated before, rather than something people complain about.
◧◩◪
3. echelo+OZc[view] [source] 2025-12-05 19:01:09
>>saghm+pWc
Holy shit, I'd love to see NaN as a proper sum type. That's the way to do it. That would fix everything.
◧◩◪◨
4. amelia+DNd[view] [source] 2025-12-05 23:28:39
>>echelo+OZc
I suspect that this would result in a lot of .unwrap() calls or equivalent, and people would treat them as line noise and find them annoying.

An approach that I think would have most of the same correctness benefits as a proper sum type while being more ergonomic: Have two float types, one that can represent any float and one that can represent only finite floats. Floating-point operations return a finite float if all operands are of finite-float type, or an arbitrary float if any operand is of arbitrary-float type. If all operands are of finite-float type but the return value is infinity or NaN, the program panics or equivalent.

(A slightly more out-there extension of this idea: The finite-float type also can't represent negative zero. Any operation on finite-float-typed operands that would return negative zero returns positive zero instead. This means that finite floats obey the substitution property, and (as a minor added bonus) can be compared for equality by a simple bitwise comparison. It's possible that this idea is too weird, though, and there might be footguns in the case where you convert a finite float to an arbitrary one.)

◧◩◪◨⬒
5. aw1621+Pme[view] [source] 2025-12-06 05:32:16
>>amelia+DNd
> Have two float types, one that can represent any float and one that can represent only finite floats. Floating-point operations return a finite float if all operands are of finite-float type, or an arbitrary float if any operand is of arbitrary-float type. If all operands are of finite-float type but the return value is infinity or NaN, the program panics or equivalent.

I suppose there's precedent of sorts in signaling NaNs (and NaNs in general, since FPUs need to account for payloads), but I don't know how much software actually makes use of sNaNs/payloads, nor how those features work in GPUs/super-performance-sensitive code.

I also feel that as far as Rust goes, the NonZero<T> types would seem to point towards not using the described finite/arbitrary float scheme as the NonZero<T> types don't implement "regular" arithmetic operations that can result in 0 (there's unsafe unchecked operations and explicit checked operations, but no +/-/etc.).

[go to top]