Special values like NaN are half-assed sum types. The latter give you compiler guarantees.
In my opinion it’s overall cleaner if the compiler handles enforcing it when it can. Something like “ensure variable is initialized” can just be another compiler check.
Combined with an effects system that lets you control which errors to enforce checking on or not. Nim has a nice `forbids: IOException` that lets users do that.
Only sometimes, when the compiler happens to be able to understand the code fully enough. With sum types it can be enforced all the time, and bypassed when the programmer explicitly wants it to be.
tbh this system (assuming it works that way) would be more strict at compile-time than the vast majority of languages.
If you actually want the compiler to check this on the level of the type system, it'd have to be `NonNaNFloat | NaN`. Then you can check which one you have and continue with a float that is guaranteed to not be NaN.
But (importantly) a NonNaNFloat is not the same as a float, and this distinction has to be encoded in the type system if you want to take this approach seriously. This distinction is NOT supported by most type systems (including Rust's std afaik, fwiw). It's similar to Rust's NonZero family of types.
Hypothetically, no, the float type would not admit NaNs. You would be prevented from storing NaNs in them explicitly, and operations capable of producing NaNs would produce a `float | nan` type that is distinct from float, and can't be treated like float until it's checked for NaN.
And I'm not sure why it's being discussed as though this is some esoteric language feature. This is precisely the way non-nullable types work in languages like Kotlin and TypeScript. The underlying machine representation of the object is capable of containing null values, yes, but the compiler doesn't let you treat it as such (without certain workarounds).
This is fine, I guess, but it will cause a bunch of problems since e.g. Division of two floats has to be able to return NaNs. At that point you either need to require a check to see if the value is NaN (inconvenient and annoying) or allow people to just proceed. Not sure I am exactly sold on this so far.
The parent commenter stated that sum types work differently from a hypothetical float / NaN split, because compilers can't always "understand the code fully enough" to enforce checks. I simply responded that that is not true in principle, since you could just treat non-nan floats the same way that many languages treat non-null types.
Indeed, everything you're describing about non-nan floats applies equally to sum types - you can't operate on them unless you pattern match. You're highlighting the exact point I'm trying to make!
The fact that you consider this system "inconvenient", is entirely irrelevant to this discussion. Maybe the designer of Nim simply cares more about NaN-safety than you or I do. Who knows. Regardless, the original statement (that sum types and non-nan floats can't work the same way) is incorrect.