Enum literals, good? bad? what do you think?
Steven Schveighoffer
schveiguy at gmail.com
Thu Jul 22 18:16:13 UTC 2021
On 7/22/21 1:19 PM, Walter Bright wrote:
> On 7/22/2021 9:16 AM, Steven Schveighoffer wrote:
>> ```d
>> enum A
>> {
>> one,
>> two,
>> three
>> }
>>
>> enum B
>> {
>> one,
>> two,
>> three
>> }
>>
>> void foo(A a, B b) {... }
>>
>> // how to call foo without having to specify `A.one` or `B.one`?
>> ```
>>
>> In Swift, `.symbol` is specifically for type properties, and fit
>> perfectly for enums (and other things, see
>> [here](https://www.swiftbysundell.com/tips/using-dot-syntax-for-static-properties-and-initializers/)).
>
>
>
> How does that interact with function overloading?
Swift is known for "giving up" on expression inference, so possibly it
could lead there.
But note that Swift (and objective C) have significant parameter names,
which means in many cases you *must* name the parameters when calling.
This helps with overloading quite a bit (in fact, in Objective C there
was no overloading, as the parameter names were part of the function name).
Which is to say, the situation in Swift is definitely different than the
situation in D. Overloads are handled differently, and expectations are
significantly different.
I tried out some stuff:
```swift
import Foundation
enum Foo {
case a
case b
case c
}
enum Bar {
case a
case b
}
func test(_ : Foo) { print("test a"); }
func test(_ : Bar) { print("test b"); }
test(.a) // error, ambiguous
test(Foo.a) // test a
test(Bar.a) // test b
test(.c) // test a
```
So it seems to work as one might expect. Since `.c` can only match the
first, it's used.
>
> I looked at the Swift reference manual
> https://docs.swift.org/swift-book/ReferenceManual/Expressions.html and
> couldn't find answers there.
>
> Seems to me there'd be a combinatorial explosion as the resolver will
> have to re-run the match for all different resolutions for
> `.identifier`.
But what is "all" resolutions? A combinatorial explosion of 1 or 2
possibilities isn't bad. Remember, the symbol lookup *requires* a
contextual type. For example:
```swift
var x = .identifier // Compiler error, no type, even if only one type in
scope has a member `identifier`
var y : SomeEnum = .identifier // OK
var z : SomeEnum
z = .identifer // OK, we infer the meaning from the type of z
```
I know D doesn't do this. But it's also not the same as what you are saying.
> Even if the compiler does try them all and find a best
> match, for the user reading the code I doubt it would be straightforward
> to figure out manually which is the right match. It's already hard enough.
The identifier comes from the expression target's inferred type. There
are still ambiguous cases, where the compiler is going to give up. But
the lookup doesn't involve the whole world either.
Before you go on arguing that D doesn't do this, and shouldn't, I know.
It's not that I'm trying to convince you that it should, I'm just
showing what has been requested and how it differs from the "mixin
solution".
>
> With the alias mixin proposed, the answer is simple. Two different enums
> in the same scope with the same member names will cause a compile time
> error.
The answer is, there is no shortcut, just type out the full enum names.
With Swift you do not need to.
-Steve
More information about the Digitalmars-d
mailing list