-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Anonymous sum types #8277
Comments
I think we can accommodate these use cases reasonably easily with some more named generic sum types in the stdlib like Either. Maybe Any3, Any4, Any5, etc. |
Or possibly there's just not much of a use case, Haskell seems to have gotten along with only |
This (either anonymous or named-AnyN) would be good for the select interface:
Would enable a natural extension without nesting Either types. |
With the removal of conditions, error handling this has become a more urgent need. For example, at https://github.com/chris-morgan/diffbot-rust-client/blob/364ca8d978f669a278ac2d38804c3926d33f123d/src/diffbot/lib.rs#L233..L259 (code is out of date—now with the removal of conditions We have I would like to be able to use match err {
ApiError(_) => unimplemented!(),
json::Error(_) => unimplemented!(),
IoError(_) => unimplemented!(),
} But assignation does not require any form of wrapping, e.g.: fn x() -> Result<(), ApiError | json::Error | IoError {
write!(...)
} Put another way, sum types can be introduced silently; (I had a much longer writeup of the problems and solutions I saw, but lost it some time back. For now, I guess this will do.) |
@chris-morgan: This proposal feels more like (Which is not to say that something like
Only because of verbosity, or for other reasons too? (FWIW, under my proposal I think you might write |
The scheme that I have proposed does have certain issues which would need to be resolved; a naïve implementation would make some error handling more difficult as it arbitrary expansion of types. For example: let mut a = 7i;
a = 5u; At present this is a nice simple thing: type error, Probably the best way around that is that the type inferrer be incapable of introducing sum types. Thus, the fn x() -> int | uint {
let out = 5i;
// Do something
out
} In a case like that By the way, I also imagine sum types as automatically implementing all traits that all of their types implement—this would make a type like But you would be able to have simpler ones like Unfortunately, all of these automatic trait implementation notions involve combinatorial explosion with generics. |
@chris-morgan: We'd also need special match syntax to test whether it's a |
@mneumann my initial suggestion was using the type path, which would yield it |
@chris-morgan you haven't addressed how to handle It would be good to collect some research and any prior art about languages with anonymous sum types (preferably, statically typed languages). |
@huonw You're right, I forgot that. OK, here we go:
I will define sum types as commutative (viz. Given a generic To clarify how generic matching would operate: fn x<T>(t: T | int) {
match t {
T(t) => unimplemented!(),
int(t) => unimplemented!(),
}
}
x(42u); // Fine. T = uint
x(42i); // Not fine: T = <type error>
x::<bool>(42i); // Fine. T = bool Hmm… suddenly I started wondering about |
I feel that the two proposals in mind have different use cases. The first approach, The second approach, my Well, I have demonstrated cases where my proposal would be useful in existing code. Can anyone come up with a case where |
@chris-morgan Indeed, the two are very different things with some superficial similarities, as I noted earlier. We should also clarify terminology. I don't think what you're describing can be accurately called "anonymous sum types", because they're not sum types. I'm not remotely an expert in this area, but it sounds much closer to something like union types (see one, two). (It might be worth discussing the two in separate issues? I don't mind having them both here, but it might help to reduce confusion.) W.r.t. anonymous sum types (my proposal), there's no strongly motivating use case that I know of, it's just niceties and ergonomic things like:
Arguably, any time you might want to use an anonymous sum, it would improve readability to introduce an explicit You haven't explicitly answered my question with regards to what the motivation for these union-ish types is. I get that you want to make error handling nicer, but could you precisely enumerate what bothers you about the current situation, what properties any solution should have (i.e. when could it be considered "solved"), and so forth? (For instance, is your problem primarily with syntactic verbosity or semantic expressiveness? If it's the former, introducing a potentially-far-reaching type system feature to deal with it might not be the most cost-effective solution.) |
This issue has been moved to the RFCs repo: rust-lang/rfcs#294 |
fix `needless_question_mark` not considering async fn closes rust-lang#8277 changelog: [`needless_question_mark`] Fix FN on async functions
Rust has an anonymous form of product types (structs), namely tuples, but not sum types (enums). One reason is that it's not obvious what syntax they could use, especially their variants. The first variant of an anonymous sum type with three variants needs to be syntactically distinct not just from the second and third variant of the same type, but also from the first variant of all other anonymous sum types with different numbers of variants.
Here's an idea I think is decent:
A type would look like this:
(~str|int|int)
. In other words, very similar to a tuple, but with pipes instead of commas (signifying or instead of and).A value would have the same shape (also like tuples), with a value of appropriate type in one of the "slots" and nothing in the rest:
(Nothing is a bikeshed, other possible colors for it include whitespace,
.
, and-
._
means something is there we're just not giving it a name, so it's not suitable for "nothing is there".!
has nothing-connotations from the negation operator and the return type of functions that don't.)I'm not sure whether this conflicts syntax-wise with closures and/or negation.
Another necessary condition for this should be demand for it. This ticket is to keep a record of the idea, in case someone else has demand but not syntax. (If the Bikesheds section of the wiki is a better place, I'm happy to move it.)
The text was updated successfully, but these errors were encountered: