[IDEA] Implied enum types

Please note that this is my first time using this forum.

I saw a similar issue, but it was closed due to inactivity.

  • Feature Name: Implied enums

Summary

A proposal to allow enums to be implied when inputting parameters.

Motivation

When I tried swift I noticed how simple it was to call functions without having messy enum definitions taking up space. I have used this syntax and believe it is quite convenient.

I have seen a similar issue but it has been closed.

Proposed solution

I think we could have a similar syntax that could fit with the rust language.

enum Target {
    Everyone,
    World
}

fn greet(target: Target) {
    println!("Hello {}", match target {
        Everyone => "everyone",
        World => "world"
    });
}

fn main() {
    greet(::World);
}

I think all implied enums should be like this rather than maybe an _:: because IDEs can show the implied enum:
Screenshot 2023-02-15 at 10.51.34 AM

Prior art

Swift syntax:

enum Target: Int {
    everyone = 0
    world = 1
}

// Yes, you could use "rawvalue" but this is an example
func greet(target: Target) {
    switch target {
        case .everyone:
            print("Hello Everyone!")
        case .world:
            print("Hello World!")
    }
}

greet(.world);
1 Like

FWIW you can of course use Target::*;, which is how the standard prelude brings the variants of the Option and Result enums into scope.

2 Likes

Just ::World doesn't work well, because ::name is already allowed, with the semantics of name being the name of an external crate.

4 Likes

Reusing my posts from the last few times:

9 Likes

Sorry, you mentioned many different things within these posts. I see that you are saying this won't work because of:

  • Rust enums being different
  • Unclear code

Is this correct?

If so, one of my main ideas was to use IDE intelligence to display the actual enum. For rust enums being different, couldn't we just import them in the background?

Also I have seen the playground but this doesn't seem relevant doc.

As stated, I'm new to this forum, please help me understand .

There's also an argument that it goes against what's considered idiomatic in Rust code. You see, one of the values of Rust is to be explicit. As convenient as the feature might sometimes be, implicit enums wouldn't mesh very well with that value IMO.

Aside from that, earlier in this topic the (quite valid) point was made that you can just use use MyEnum::*;, after which you can just use the unqualified enum variant names. That is perfectly workable in practice when things would get too verbose otherwise.

I'd be wary of relying too much on IDE hints for readability - not everyone uses IDEs/language servers, and there's a lot of scenarios where you might need to read code without one (for example, a code review on GitHub).

4 Likes

There was also proposals to have greet(_::World); but so far they have not reach consensus. One point that was against it is that in Rust it’s idiomatic to not have the enum name repeated in the variants and eliding the enum name could to do it (like Action::ActionDown). That being said, I think that in match expression it would be useful to elide the enum name since it’s already clear about which enum we are talking about.

Yeah, thats where I got my inspiration :slight_smile:.

That is a very good point. only if github had a language server.

I will research how swift solved this.

The problem isn't just the long syntax, it's importing all these files. Also it's not neat.

Yup, I wonder what could work in place.

How are files related to this, other than that the code is contained in one?

It's not like a new sytax that requires a new feature, it literally expands from:

use caller::call;
call(/*enums::target */::hello);

To:

use caller::call;
use enums::target;
call(target::hello);

Wouldn't the it be implied by the function you're calling? Also, there are many ways to write unreadable code in rust and just like many other things, it could just be fixed by rustfmt or just a rule in rustfmt. It's opt-in. Not required O_o.


Also I think the syntax _:: is actually pretty nice and I think it would work well.

If you know the function's signature, then yes. But without an ide, and with unfamiliar code it's often not the case.

But add a new syntax just to be linted against rustfmt just feels really wrong.

That's not what I meant. What I'm saying is that this syntax could be dissalowed in some projects. Me and many other people would want to keep it on though.

What this refers to is the phenomenon of language dialects. C++ has it, but only by "virtue" of being so complex and so full of footguns that just out of pragmatism choices need to be made w.r.t. which features to use and which to avoid.

This is something I personally consider undesirable, as it just increases project complexity without a clear benefit in return.