Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAnonymous sum types #8277
Comments
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
Or possibly there's just not much of a use case, Haskell seems to have gotten along with only |
This comment has been minimized.
This comment has been minimized.
|
This (either anonymous or named-AnyN) would be good for the select interface:
Would enable a natural extension without nesting Either types. |
This comment has been minimized.
This comment has been minimized.
|
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.) |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
@chris-morgan: We'd also need special match syntax to test whether it's a |
This comment has been minimized.
This comment has been minimized.
|
@mneumann my initial suggestion was using the type path, which would yield it |
This comment has been minimized.
This comment has been minimized.
|
@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). |
This comment has been minimized.
This comment has been minimized.
|
@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 = boolHmm… suddenly I started wondering about |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
@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.) |
chris-morgan
referenced this issue
May 23, 2014
Merged
RFC: Bounds on trait objects should be separated with `+` #87
chris-morgan
referenced this issue
Aug 22, 2014
Closed
RFC: error conventions and syntactic support (including changes to macro syntax) #204
This comment has been minimized.
This comment has been minimized.
|
This issue has been moved to the RFCs repo: rust-lang/rfcs#294 |
glaebhoerl commentedAug 3, 2013
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.)