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 #294
Comments
canndrew
referenced this issue
Jun 2, 2015
Closed
wishlist: Way to express `Fn` trait like `(FnOnce() -> !)` #1120
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
What's the state of this? |
burdges
referenced this issue
Dec 16, 2015
Merged
First-class error handling with `?` and `catch` #243
nrc
added
the
T-lang
label
Aug 17, 2016
This comment has been minimized.
This comment has been minimized.
Rufflewind
commented
Jan 27, 2017
|
Compared to tuples, anonymous enums would become increasingly tedious to use since a match statement would have
The syntax would be compatible with a future extension that allows enums to be declared with named choices:
|
This comment has been minimized.
This comment has been minimized.
|
I think the feature would be more useful without allowing matching, just doing trait dispatch. I guess it's a different feature, where |
This comment has been minimized.
This comment has been minimized.
plietar
commented
Feb 17, 2017
|
@eddyb I've been putting some thoughts into a feature like that |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Feb 17, 2017
|
I'd think an |
This comment has been minimized.
This comment has been minimized.
OvermindDL1
commented
Feb 17, 2017
|
Passing by, but if you are curious in syntax's then OCaml has anonymous sum types called Polymorphic Variants. Basically they are just a name, like `Blah, which can have optional values. An example of the syntax: # let three = `Int 3;;
val three : [> `Int of int ] = `Int 3
# let four = `Float 4.;;
val four : [> `Float of float ] = `Float 4.
# let nan = `Not_a_number;;
val nan : [> `Not_a_number ] = `Not_a_number
# let list = [three; four; nan];;
val list : [> `Float of float | `Int of int | `Not_a_number ] listThe In the back-end at assembly time the names are given a globally unique integer (in the current implementation it is via hashing, a chance of collision but overall the chance is extremely low as well as warnings can be put in place to catch them), however I've seen talk of making a global registry so they just get incremented on first access efficiently. A plain Polymorphic Variant with no data is represented internally as an integer: `BlahBecomes the integer `Blah (42, 6.28)Gets encoded internally as an array of two fields in assembly, the first is the above number as before, the second is the pointer to the data of the tuple (although in most cases these all get inlined into the same memory in OCaml due to inlining and optimization passes). In the typing system the above would be However, about Polymorphic variants is that they can be opened or closed. Any system can pass any of them that they want, including passing through if you want. For example, a simple way to handle something like a generic event in OCaml would be like: let f next x = match x with
| `Blah x -> do_something_with x
| `Foobar -> do_something_else ()
| unhandled -> next unhandledWhich is entirely type safe, dependent on what each function handles down the chain and all. The big thing on the typing system is that things can be open or close typed, I.E. they either accept any amount of Polymorphic Variants or a closed set of Polymorphic Variants. If something like anonymous sum type here were to be accepted then that concept would be exceedingly useful while being very easy and very fast to statically type. |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Mar 15, 2017
|
Anonymous sum types might interact with
You could make this make sense with an anonymous sum type of the form One could do it in
so the above code becomes
I could imagine some |
This comment has been minimized.
This comment has been minimized.
dobkeratops
commented
Jul 14, 2017
|
this might sound like a weird hack , but how about just making A|B sugar for 'Either', i suppose it might get even weirder to start composing A|B|C as Either<A,Either<B,C>> or have that mapping to something . What if there was some sort of general purpose 'operator overloading' in the 'type syntax' , allowing people code to experiment with various possibilities - see what gains traction |
This comment has been minimized.
This comment has been minimized.
|
@dobkeratops I'd rather just have a |
This comment has been minimized.
This comment has been minimized.
Sgeo
commented
Aug 7, 2017
|
I wrote some code that could potentially fit into a library now that type macros are stable: https://gist.github.com/Sgeo/ecee21895815fb2066e3 Would people be interested in this as a crate? |
burdges
referenced this issue
Dec 25, 2017
Closed
Figure out a way to ergonomically match against impl traits? #2261
cramertj
referenced this issue
Mar 15, 2018
Open
Tracking issue for `impl Trait` (RFC 1522, RFC 1951, RFC 2071) #34511
This comment has been minimized.
This comment has been minimized.
Ekleog
commented
Apr 22, 2018
•
|
I've just come upon this issue, while looking for a way to avoid having some gross code that simply doesn't want to go away (actually it's slowly increasing, started at 8 variants and passed by 9 before reaching 12): use tokio::prelude::*;
pub enum FutIn12<T, E, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12>
where
F1: Future<Item = T, Error = E>, // ...
{
Fut1(F1), // ...
}
impl<T, E, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12> Future
for FutIn12<T, E, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12>
where
F1: Future<Item = T, Error = E>, // ...
{
type Item = T;
type Error = E;
fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
use FutIn12::*;
match *self {
Fut1(ref mut f) => f.poll(), // ...
}
}
}I was thus thinking that it'd be great to have anonymous sum types that automatically derived the traits shared by all their variants, so that I could get rid of this code and just have my |
This comment has been minimized.
This comment has been minimized.
|
As I wrote here I think this use case would be better addressed by something modelled after how closures work. |
This comment has been minimized.
This comment has been minimized.
alexreg
commented
Apr 22, 2018
|
I don’t think it would be wise to make anonymous sum types nominally typed, as you seem to suggest. Structural typing, as with tuples, is far more useful and less surprising to the programmer. |
This comment has been minimized.
This comment has been minimized.
|
@alexreg What they're saying is that the specific use-case of wanting to return Therefore, anonymous sum types are separate (and mostly unrelated) from that use case. |
This comment has been minimized.
This comment has been minimized.
alexreg
commented
Apr 22, 2018
•
|
@Pauan Oh, well I agree with that. As long as we consider these things two separate features, fine. Thanks for clarifying. |
This comment has been minimized.
This comment has been minimized.
Ekleog
commented
Apr 23, 2018
|
Oh indeed good point, thanks! Just opened #2414 to track this separate feature, as I wasn't able to find any other open issue|RFC for it :) |
CAD97
referenced this issue
Oct 18, 2018
Open
Tracking issue for RFC 2535, 2530, 2175, "Or patterns, i.e `Foo(Bar(x) | Baz(x))`" #54883
This comment has been minimized.
This comment has been minimized.
eaglgenes101
commented
Nov 2, 2018
|
I'm planning to get out a pull request for this proposed RFC. Most of you following this thread probably know that a number of proposals like this were rejected for being too complex, so its focus is minimalism and implementation simplicity rather than ergonomics and features. Any words before I get it out? (I've asked this question in multiple other areas to try to collect as much feedback before getting the proposed RFC out, fyi) https://internals.rust-lang.org/t/pre-rfc-anonymous-variant-types/8707/76 |
rust-highfive commentedSep 24, 2014
Saturday Aug 03, 2013 at 23:58 GMT
For earlier discussion, see rust-lang/rust#8277
This issue was labelled with: B-RFC in the Rust repository
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.)
SEE ALSO