The Unreasonable Effectiveness of Naming Integers
ziglang.org
ziglang.org
var age: 18 ... 120;
This is more than 50 years old Pascal. As far as I know the only mainstream language that supports this in its type system (and compile-time checked) today is Ada[1]. Blows my mind. I never got over the loss when I switched to C.[1] I think you could convince Rust to do something pretty close but a bit uglier syntax-wise.
var age: range[18..120]Newtypes are effective for any kind of value, not just numbers.
newtype PostalCode = PostalCode String
newtype LicenseKey = LicenseKey String
Now you won't be accidentally mixing postal codes and license keys. Every language should support newtypes (and algebraic types). private enum Derp { }
private enum Foo { }
var derp = (Derp)12;
var foo = (Foo)99;
foo = derp;
However, this is definitely a hack, and I sort-of feel the same about the Zig solution from the article. Would be nice if languages had 'cleaner' support for this? struct Foo(u32);
No? record struct Foo(int Value);
In F#, this is instead done with // Foo and Bar cannot be assigned to each other
type Foo = Foo of int
type Bar = Bar of int
// Foo and Bar can be assigned to each other
type Foo = int
type Bar = int
The first variant uses single-case unions. It's a bit unfortunate that they also default to classes over structs unless you annotate them with [<Struct>], partially fixed by escape analysis though.The enum trick is the tersest and will also serialize correctly in most cases, but I have never seen anyone use it like that before.
The basic idea is the "newtype" pattern: different types may have exactly the same valid set of values, but not be interchangeable.
E.g. kilograms and US customary pounds, or meters and miles. If you've got a function `f(distance: double)` where `distance` needs to be in kilometers but your program also handles miles, it's nice to be able to define a type for kilometers that's different from the type for miles so the function won't compile if passed in miles incorrectly. So you get `f(distance: kilometers)`. That also stops someone passing in pounds to `f`, or any other such nonsense.