Jump to page: 1 2
Thread overview
Proposal: overload conflict resolution
Dec 10, 2006
Chris Miller
Dec 10, 2006
Kristian Kilpi
Dec 10, 2006
Frits van Bommel
Dec 10, 2006
Lars Ivar Igesund
Dec 10, 2006
Rioshin an'Harthen
Dec 10, 2006
Frits van Bommel
Dec 11, 2006
Karen Lanrap
Dec 10, 2006
Chris Miller
Dec 10, 2006
Frits van Bommel
Dec 10, 2006
Alexander Panek
Dec 11, 2006
Pragma
Dec 11, 2006
Derek Parnell
December 10, 2006
Given the following function prototypes:
   void foo(char[] s);
   void foo(wchar[] s);
   void foo(dchar[] s);

Currently, if you try to do foo("hello"), the compiler will complain because string literals simulteneous match all the above types.

Proposal:
   void foo(default char[] s);
   void foo(wchar[] s);
   void foo(dchar[] s);

foo("hello")  will now select the char[] version because it was marked as the default type in the overload.

What it does not do:
   1) Resolve conflicts between different scopes.
   2) Override exact matches.

The way overloads work now is helpful in some cases, but in other cases, it's perfectly fine to prefer an overload over another.


Example where you do not want a default overload: working with binary, e.g. writing to Stream or Socket, where the wrong type can screw up the format or transmission.

Example where you do: custom string object's constructor that wants to allow char[], wchar[] and dchar[] types, but wants to default string literals to char[].


The compiler would go down the line of parameters of overloads, and upon any conflicts, would look for default to resolve them. If default is used to resolve conflicts in more that one of the functions, it's an actual conflict.

Strange example:
   void bar(default char[] s, int x);
   void bar(char[] s, default long x);

Note: this example probably wouldn't actually be used; as with most language constructs, there's a way to abuse it, but this example gets a point across that it at least has logic:
bar("hello", 42)  chooses the first one because the string literal conflicted and went with the default one.
bar("hello"c, 42)  chooses the second one; the string literal specified char[] (with the c) and then had a conflict with the second parameter, where default resolved it.


The programmer knows which overloads, if any, can be preferred over others, because this feature works only confined within one scope, and so it is safe to let him choose for you.


Where this can be useful:
   1) String literals conflicting with char[], wchar[] and dchar[].
   2) null conflicting with string types, delegates, pointers, and class references.
   3) Integer literals conflicting with the number types.
   4) Different levels of derived classes conflicting with each other.


Thanks,
- Chris
December 10, 2006
On Sun, 10 Dec 2006 16:36:51 +0200, Chris Miller <chris@dprogramming.com> wrote:
> Given the following function prototypes:
>     void foo(char[] s);
>     void foo(wchar[] s);
>     void foo(dchar[] s);
>
> Currently, if you try to do foo("hello"), the compiler will complain because string literals simulteneous match all the above types.
>
> Proposal:
>     void foo(default char[] s);
>     void foo(wchar[] s);
>     void foo(dchar[] s);
>
[snip]


I have hoped that something like this would be possible in C++, and now, in D. Gets my vote!
December 10, 2006
Chris Miller wrote:
> Given the following function prototypes:
>    void foo(char[] s);
>    void foo(wchar[] s);
>    void foo(dchar[] s);
> 
> Currently, if you try to do foo("hello"), the compiler will complain because string literals simulteneous match all the above types.
> 
> Proposal:
>    void foo(default char[] s);
>    void foo(wchar[] s);
>    void foo(dchar[] s);
<snip>
> The compiler would go down the line of parameters of overloads, and upon any conflicts, would look for default to resolve them. If default is used to resolve conflicts in more that one of the functions, it's an actual conflict.
> 
> Strange example:
>    void bar(default char[] s, int x);
>    void bar(char[] s, default long x);

I like the basic idea, but maybe it gets a bit to hairy when multiple parameters can have this attribute...

Maybe it should be an attribute of the function instead?
Then it becomes quite clear, I think: if there are multiple equally-good matches and among them the number of overloads with the attribute is anything other than one (that is, none or at least two) it's still an error, otherwise the one declared 'default' is picked.
December 10, 2006
> 
> Maybe it should be an attribute of the function instead?


This gets my vote
December 10, 2006
Frank Benoit (keinfarbton) wrote:

>> 
>> Maybe it should be an attribute of the function instead?
> 
> 
> This gets my vote

Yes, this might work.

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
December 10, 2006
"Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote:
> Chris Miller wrote:
>>
>> Strange example:
>>    void bar(default char[] s, int x);
>>    void bar(char[] s, default long x);
>
> I like the basic idea, but maybe it gets a bit to hairy when multiple parameters can have this attribute...
>
> Maybe it should be an attribute of the function instead?
> Then it becomes quite clear, I think: if there are multiple equally-good
> matches and among them the number of overloads with the attribute is
> anything other than one (that is, none or at least two) it's still an
> error, otherwise the one declared 'default' is picked.

So, we'd have something like

default void foo(char[] s);
void foo(wchar[] s);
void foo(dchar[] s);

with only one function of the same name at most with default...

I like this :). Votes++ for this modification.


December 10, 2006
On Sun, 10 Dec 2006 11:58:35 -0500, Frits van Bommel <fvbommel@REMwOVExCAPSs.nl> wrote:

> Chris Miller wrote:
>> Given the following function prototypes:
>>    void foo(char[] s);
>>    void foo(wchar[] s);
>>    void foo(dchar[] s);
>>  Currently, if you try to do foo("hello"), the compiler will complain because string literals simulteneous match all the above types.
>>  Proposal:
>>    void foo(default char[] s);
>>    void foo(wchar[] s);
>>    void foo(dchar[] s);
> <snip>
>> The compiler would go down the line of parameters of overloads, and upon any conflicts, would look for default to resolve them. If default is used to resolve conflicts in more that one of the functions, it's an actual conflict.
>>  Strange example:
>>    void bar(default char[] s, int x);
>>    void bar(char[] s, default long x);
>
> I like the basic idea, but maybe it gets a bit to hairy when multiple parameters can have this attribute...
>
> Maybe it should be an attribute of the function instead?
> Then it becomes quite clear, I think: if there are multiple equally-good matches and among them the number of overloads with the attribute is anything other than one (that is, none or at least two) it's still an error, otherwise the one declared 'default' is picked.

I thought of it and generally agree it reduces complexity, but doesn't give as much control. Consider one name that has overloads with many different types, like toString; it has conflicts with numbers, strings, and whatever else. Also consider when more than one parameter is involved. I'm not sure which is the better tradeoff.
December 10, 2006
Rioshin an'Harthen wrote:
> "Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote:
>> Chris Miller wrote:
>>> Strange example:
>>>    void bar(default char[] s, int x);
>>>    void bar(char[] s, default long x);
>> I like the basic idea, but maybe it gets a bit to hairy when multiple parameters can have this attribute...
>>
>> Maybe it should be an attribute of the function instead?
>> Then it becomes quite clear, I think: if there are multiple equally-good matches and among them the number of overloads with the attribute is anything other than one (that is, none or at least two) it's still an error, otherwise the one declared 'default' is picked.
> 
> So, we'd have something like
> 
> default void foo(char[] s);
> void foo(wchar[] s);
> void foo(dchar[] s);
> 
> with only one function of the same name at most with default...

I see no reason why you can't declare multiple 'default's, as long as you make sure they don't conflict. Basically, only one would be allowed in the overload set without it being an error.

For instance:
/// UTF conversion
default char[] toString(char[]);
char[] toString(wchar[]);		/// ditto
char[] toString(wchar[]);		/// ditto

/// Converts a number to a printable representation
default char[] toString(int);
char[] toString(uint);		/// ditto

I don't think these will conflict.
Now, which one of the latter two to make the default, that's another question... (I just arbitrarily picked one)

> I like this :). Votes++ for this modification.
December 10, 2006
Chris Miller wrote:
> On Sun, 10 Dec 2006 11:58:35 -0500, Frits van Bommel <fvbommel@REMwOVExCAPSs.nl> wrote:
>> Maybe it should be an attribute of the function instead?
>> Then it becomes quite clear, I think: if there are multiple equally-good matches and among them the number of overloads with the attribute is anything other than one (that is, none or at least two) it's still an error, otherwise the one declared 'default' is picked.
> 
> I thought of it and generally agree it reduces complexity, but doesn't give as much control. Consider one name that has overloads with many different types, like toString; it has conflicts with numbers, strings, and whatever else. Also consider when more than one parameter is involved. I'm not sure which is the better tradeoff.

My version allows numbers and strings, as long as only one 'default' is in the overload set. Numbers and strings will never conflict, AFAIK.

When it comes to multiple parameters, what kind of use case did you have in mind?
I can't think of any at the moment, but that may just be my lack of imagination playing up again :).
December 10, 2006
As I've already mentioned in #d, I /actually/ like it how it works now (explicit usage; e.g. you have to append c/w/d each time you pass a string literal). This concept is still the way to go, IMHO, though as D is a language inventing/implementing so much nice paradigms already, this one should have a go, too.

It's basically syntactic sugar, but also adds the capability to 'control' usage of functions, which is a good thing.

Long story short:
Has my vote. :P

Kind regards,
Alex

Chris Miller wrote:
> Given the following function prototypes:
>    void foo(char[] s);
>    void foo(wchar[] s);
>    void foo(dchar[] s);
> 
> Currently, if you try to do foo("hello"), the compiler will complain because string literals simulteneous match all the above types.
> 
> Proposal:
>    void foo(default char[] s);
>    void foo(wchar[] s);
>    void foo(dchar[] s);
> 
> foo("hello")  will now select the char[] version because it was marked as the default type in the overload.
> 
> What it does not do:
>    1) Resolve conflicts between different scopes.
>    2) Override exact matches.
> 
> The way overloads work now is helpful in some cases, but in other cases, it's perfectly fine to prefer an overload over another.
> 
> 
> Example where you do not want a default overload: working with binary, e.g. writing to Stream or Socket, where the wrong type can screw up the format or transmission.
> 
> Example where you do: custom string object's constructor that wants to allow char[], wchar[] and dchar[] types, but wants to default string literals to char[].
> 
> 
> The compiler would go down the line of parameters of overloads, and upon any conflicts, would look for default to resolve them. If default is used to resolve conflicts in more that one of the functions, it's an actual conflict.
> 
> Strange example:
>    void bar(default char[] s, int x);
>    void bar(char[] s, default long x);
> 
> Note: this example probably wouldn't actually be used; as with most language constructs, there's a way to abuse it, but this example gets a point across that it at least has logic:
> bar("hello", 42)  chooses the first one because the string literal conflicted and went with the default one.
> bar("hello"c, 42)  chooses the second one; the string literal specified char[] (with the c) and then had a conflict with the second parameter, where default resolved it.
> 
> 
> The programmer knows which overloads, if any, can be preferred over others, because this feature works only confined within one scope, and so it is safe to let him choose for you.
> 
> 
> Where this can be useful:
>    1) String literals conflicting with char[], wchar[] and dchar[].
>    2) null conflicting with string types, delegates, pointers, and class references.
>    3) Integer literals conflicting with the number types.
>    4) Different levels of derived classes conflicting with each other.
> 
> 
> Thanks,
> - Chris
« First   ‹ Prev
1 2