I don’t know where None comes from (what’s the T in Option<T>?)
Assuming you meant (), that’s a unit type with one valid value. It’s a ZST, but can be created and returned.
! is a bottom type. It’s uninhabited. Can’t be created. Functions can never return it because they can never construct it. So why’s this useful? It can be coerced to any type.
Because the set of valid values for ! is the null set, by contradiction, there do not exist any values valid for the type ! that are invalid for any other type T. Therefore, all valid values of ! are also valid values of any other type T, and you can always convert from it to any other type.
Notably, this is already possible, but language support for it isn’t amazing:
enum A {}
fn bar(a: A) {
let foo: Box<Arc<Rc<Mutex<String>>>> = match a {}
}
Heck you can even do this today:
// `loop {}` never returns, so its type is `!`:
let blah: String = loop {};
To me it makes no sense. Because if it never returns, then it has no return value. Therefore it makes no sense to have a type for something that does not exist.
I guess it makes sense. What I struggled with is, as the type is unusable basically and I didn’t like the idea it being a type. But for documentation reasons, it makes sense. Otherwise, it has no practical meaning. Even a comment could have the same effect.
The never type comes more from type theory and isn’t common in other languages (though TS has never). Similar to 0 or the null set, it exists as a “base case” for types. For example, where you have unions of T1 | T2 | ..., the “empty union” is the never type. Similarly, for set theory, a union of no sets is the null set, and in algebra, the summation of no numbers is 0.
In practice, because it can’t be constructed, it can be used in unique ways. These properties happen to be super useful in niche places.
I don’t know where
Nonecomes from (what’s theTinOption<T>?)Assuming you meant
(), that’s a unit type with one valid value. It’s a ZST, but can be created and returned.!is a bottom type. It’s uninhabited. Can’t be created. Functions can never return it because they can never construct it. So why’s this useful? It can be coerced to any type.Because the set of valid values for
!is the null set, by contradiction, there do not exist any values valid for the type!that are invalid for any other typeT. Therefore, all valid values of!are also valid values of any other typeT, and you can always convert from it to any other type.Notably, this is already possible, but language support for it isn’t amazing:
Heck you can even do this today:
To me it makes no sense. Because if it never returns, then it has no return value. Therefore it makes no sense to have a type for something that does not exist.
Then how would you annotate having no return value?
I guess it makes sense. What I struggled with is, as the type is unusable basically and I didn’t like the idea it being a type. But for documentation reasons, it makes sense. Otherwise, it has no practical meaning. Even a comment could have the same effect.
The never type comes more from type theory and isn’t common in other languages (though TS has
never). Similar to 0 or the null set, it exists as a “base case” for types. For example, where you have unions ofT1 | T2 | ..., the “empty union” is the never type. Similarly, for set theory, a union of no sets is the null set, and in algebra, the summation of no numbers is 0.In practice, because it can’t be constructed, it can be used in unique ways. These properties happen to be super useful in niche places.