Alternative syntax for working with enums

I think I used to like the swift way too but since we can now use Self in enums, I might actually prefer the Rust way.

I think this proposal somewhat mirrors the way hierarchical 'use' works.

I believe the Rust way to spell this would be <_>::Bar. Unfortunately, I don't believe this is inferred quite as aggressively as in Swift, so this example does not currently work. I also think it's unreasonably sigiltastic...

I think the right answer is roughly what Josh already said.

1 Like

Self::Stuff is great, but notably only works when you're in a method for a given type; the Swift design works in all contexts, which is a nice win.

(This tempts me to write up a pre-RFC proposing that; anyone know of other pre-proposals or actual proposals in that space?)

1 Like

I think that people have tried to pitch this before but were rejected.

Ok another example. I'm writing code

range: std::f64::MIN..std::f64::MAX,

I wish that instead I could do

range: std::f64::{MIN..MAX},

This syntax makes so much sense.

2 Likes

To be fair on that example, those should be associated consts on the f64 type so it's just f64::MIN..f64::MAX which isn't as bad.

3 Likes

I've seen proposals for both enum::Stuff and _::Stuff before, though I don't remember where the threads are. I don't think they got far enough to get written up in RFC format.

1 Like

I'll see if I can see how good GitHub's and Discourse's search implementations are. :+1:t3:

Edit: Discourse's is pretty good, it turns out! Found it on the first try.

I would still love to have inference that allows _::Stuff.

5 Likes

Same. In skimming through the other discussions, it seems like an improved proposal could still work. And I'd be very curious to see what the constraints would be on our ability to make a general form of it, usable with methods as well.

I don't see the problem with the currently-available use MyEnum::*;-based solution? When it is put in the body of a method or fn that uses MyEnum variants extensively, to me it seems like the extra one liner is acceptable syntactic overhead that doesn't even pollute the namespace outside the method/fn in question.

But maybe I'm missing something?

5 Likes

I'm surprised nobody has pointed out the fact that all of the example use cases are invalid?

There is no value of Value associated with the value 3.

Those are not enums. You can't use enums to implement bitflags in rust. At least, not without losing your mind if there's more than 3 bits.

What you want to do is make working with newtypes easier. Which I'm pretty sure a lot of us also want to do. Just can't agree on how.

5 Likes

I'm surprised nobody has pointed out the fact that all of the example use cases are invalid?

This is not a good faith argument.

It's more about the spirit. I have not specified what the Add operation means, maybe it's a Z2 group. Maybe Value::{a + b} == Value::a.

1 Like

What I'm saying is, you're very specifically trying to make it easier to use binary operators on enums, and I honestly cannot even remember the last time I've used a binary operator on an enum.

8 Likes

This doesn't need to be restricted to enums. We could say that Foo::{...} creates a new scope, where all items in Foo can be used. So

Foo::{
    ...
}

is equivalent to

{
    use Foo::*;
    ...
}

where Foo can be an enum, a module, a trait, etc.

However, I don't think it justifies adding a new syntax, since it doesn't make the code significantly shorter or simpler.

5 Likes

I'd be cautious of doing this. It starts to sound a lot like:

// legacy javascript
with foo {
   bar = "Hello";
}

which was found to be a huge foot-gun.

NOTE: similar "with ..." scoping has been present in many languages, and as far as I can recall, it was always found to be a foot-gun and everyone regretted having it in the language and it was eventually "deprecated".

If we did something like this for Rust, we'd have to be 100% sure it wasn't going to create problems, now or in the future, ever (which is not a bar that I think you could ever vault).

1 Like

with is only a footgun in JS because of JS-specific reasons: lack of static typing, which makes it JIT-unfriendly and can create global variables by accident. You can't create a global variable by accident in Rust, so this wouldn't apply.

1 Like

More generally, the problem with with is that it introduced dynamic scoping. i.e. the meaning of a name/identifier has to depend on what runtime values get passed into a block of code. That is indeed a giant mess no one wants in their languages any more.

But AFAICT nobody has suggested any enum syntax that would bring in truly dynamic scoping.

I don't see patterns mentioned in this thread, but I think the syntax would be very useful for matching enum variations, like Enum::{A | B | C}. I posted that as a separate idea over here.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.