On 7/1/22 2:32 PM, Walter Bright wrote:
> On 7/1/2022 8:42 AM, Steven Schveighoffer wrote:
> How I would design it:
Those are reasonable suggestions.
But just let me throw this out. I've heard from many sources that nobody understands C++ function overloading. It is described with pages of detail in the Standard. Even compiler writers only temporarily understand it while they are implementing it.
How C++ programmers deal with it is they randomly try things until it works.
This is why I'm asking the questions. I don't have experience on how to implement function overloading, and I don't know what pitfalls might be introduced from doing something like this.
> D's overloading is simpler than C++'s. But it gets more complex all the time. For example, named arguments make it more complicated.
To add more complexity would take a really really strong benefit.
There's 2 questions to answer here:
- is it possible and feasible?
- do we want to add to the complexity of the language?
Obviously if 1 is false, it's a non-starter. And it looks like you have indirectly answered that it is possible.
So on to 2:
IMO, I think the language benefits greatly from little syntax tricks like this. foreach
is a great improvement over for
. omitting parentheses can cause problems, but in general makes things far more pleasant to write/read.
I also have experience using a language (Swift) which has this feature, and it's really really nice, especially when dealing with verbose enums.
When using D enums after using Swift, I get the same feeling I do when I use C# or C++ after experiencing D metaprogramming. It feels like the D compiler knows all the information to make this simple, it just is asking me to jump through a few more hoops than it should.
I am genuinely curious why this will add too much to the complexity of overloading.
The current rules are:
- no match
- match with implicit conversions
- match with qualifier conversion (if the argument type is qualifier-convertible to the parameter type)
- exact match
That shouldn't change.
The next part says:
Each argument (including any this reference) is compared against the function's corresponding parameter to determine the match level for that argument. The match level for a function is the worst match level of each of its arguments.
OK, so a #value expression would be an "exact match" of any enum type that contains all the value literals in that expression, and a a "no match" for any other situation. The rest of the rules would apply as-is, including partial ordering, etc.
Since enums are not related, they should be completely distinct in terms of partial ordering.
Am I misunderstanding something?
> BTW, if you really want a specific case to work:
enum A { a, b, c }
alias a = A.a;
alias b = A.b;
alias c = A.c;
This could probably be automated with metaprogramming.
This doesn't scale well.
enum A { a, b, c }
alias a = A.a;
alias b = A.b;
alias c = A.c;
void bar(A a) {}
void foo()
{
int a = 5;
bar(a); // error;
}
--- mod2.d:
import mod1;
int a = 5;
void foo()
{
bar(.a); // error;
}
And I also have used with
statements, which mostly works, but I've come across some head-scratching problems when naming conflicts occur.
-Steve