4 ms·
I'm pretty fluent in C++ and Rust. You don't find much use for them in C++ because they're a relative pain in the ass without language support. std::variant i
by thrtythreeforty 3y ago
I'm pretty fluent in C++ and Rust. You don't find much use for them in C++ because they're a relative pain in the ass without language support. std::variant is a sum type, but when's the last time you used it? I bet you had lots of fun with visitors and explicit type checks.
The most motivating example is Rust's Result<T, E>. Either you have a "good" type T, or some error E occurred. Want to bubble this error up? Just do `my_result?` to get the underlying T or return E early. This idiom is pervasive and makes error handling via return codes very easy to use.
It also makes it feasible to have types that have no "default" value. In C++ you have std::unique_ptr<T> which, for various reasons, has to have a nullptr state, or else it's frustrating to use. In Rust, owned pointers Box<T> don't have an empty state. If you need a nullable pointer, you use Option<Box<T>>, which is either Some(my_box) or None. The fact that Box<T> is always pointing to a valid object is a stronger guarantee than C++ smart pointers, and is only ergonomically possible because of the Option<T> sum type.
- gpderetta 3y agooptional<non_null_unique_ptr<T>> would be completely feasible in C++. It is just that std::optional and unique_ptr do not have the right semantics out of the box, but it is not hard to roll your own. But yes, I wish C++ has good builtin sum types and proper destructuring via pattern patching. Maybe one day....
- CodesInChaos 3y agoThe problem with adding a non_null_unique_ptr<T> to C++ is that moving needs to leave behind a valid value.
- gpderetta 3y agoYou are right, but you could make it not movable (and add destructive mode hooks for optional and containers). It is still possible to return non-movable, non-copyable types from functions. But I guess ergonomics would not be good.
- soulbadguy 3y agoI love sum types, and i find it very hard to work without them when i am in C++. However your examples i don't think are particularly convincing. The examples you gave can mostly be done with std::variant<> and are simply examples are unions. (Result == std::expected) In term of non nullable smart pointer, it would be easy to enforce the the non nullability in the constructor, and have the same ergonomy as Option<Box<T>>. In fact you can do something like std::expected<std::reference<T>> but why would you instead of just std::unique_ptr and handle the nullable case. What makes sum type powerfull is to have full Algebraic DataType (tags + sum types + product types) + pattern matching + good compiler errors.