On 7/22/21 1:19 PM, Walter Bright wrote:
>On 7/22/2021 9:16 AM, Steven Schveighoffer wrote:
>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).
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:
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:
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