Of course C++ gives you the option to do any of the above, and still contains insane API contracts
Of course C++ gives you the option to do any of the above, and still contains insane API contracts
They allow for types like "String or Integer". A function which returns a value of type "A" can automatically also be assigned to a variable of type "A or B", and a function which accepts a parameter of type "A or B" can automatically also be passed a variable of type "A". This is not the case for algebraic sum types, which require somewhat inconvenient wrapping or unwrapping.
Unlike algebraic sum types, set-theoretic union types are also not necessarily mutually exclusive. E.g. a number of type "Integer or Float" could be both. Moreover, set-theoretic types can be generalized to arbitrary Boolean combinations of types, e.g. "A or (B and not C)", possibly involving disjunctions, conjunctions, and negations (since {and, or, not} are functionally complete). That's not possible for algebraic sum/product data types. Though there is no mainstream language yet with a set-theoretic type system that supports negation types.
That being said, in cases where there is no overlap I don't see why "the old way" shouldn't behave like typescript through implicit conversion as there is only one applicable constructor. Forcing explicit selection if there is overlap, but do it automatically when there is none seems like reasonable behavior that is a strict superset of what you wrote before.
There's no mainstream language with negation types, but a few good research languages with them, eg MLstruct.
[MLstruct]:https://github.com/hkust-taco/mlstruct
This is cool. Unfortunately it's also too late now. The machines have taken over programming.
Programming language development has essentially ceased, no? Because now that you have a super powerful, ceaseless special interest personality that can be ordered to be specially interested in any problem. The actual problem - a dearth of things that special interest personalities will do for little to no money - has been solved.
it's not really about traction or adoption so much as it is, the average developer values an ecosystem of free shit to use to make money.
the slow part is, the decades-long pipeline that converts the finite number of specially interested people created every year into programmers who sit around and do stuff for giant corporations, practically speaking, for free. maybe that is way too cynical but am i wrong? LLMs have had a range of programming performances, but for the whole time they have existed, they have not had difficult personalities. which is far, far more valuable. the majority of people in the white collar workforce are there because they are, #1, pleasant to work with, not good at their jobs. and look, specially interested people, who will pay huge amounts of money in order to avoid contact with people, agree!
fn six_numbers() -> (u8, u8, u8, u8, u8, u8) {
(10, 20, 30, 40, 50, 60)
}
fn in_an_array() -> [u8; 6] {
[10, 20, 30, 40, 50, 60]
}
The return type must be sized, because otherwise how can we put that anywhere? But of course your answer can just be to put it on the heap inside a Box... fn heap_numbers() -> Box<[u8]> {
let mut slice = Box::new_uninit_slice(6);
slice[0].write(10);
slice[1].write(20);
slice[2].write(30);
slice[3].write(40);
slice[4].write(50);
slice[5].write(60);
unsafe { slice.assume_init() }
}From Rust's point of view
let (a, b) = function_which_returns_a_pair();
is not special compared to the idiomatic: while let Some(item) = stack.pop() { /* do stuff with items and the stack */ }
or if we hate tuples: let [a, b] = function_returns_an_array_of_two_items();In Rust "tuple unpacking" is really just a special case of pattern matching, which is a far more powerful concept and was actually taken from OCaml.