December 11, 2006
Frits van Bommel wrote:
> as long as you make sure they don't conflict.

How to make that sure in a sufficiently large coder team?

How to find in case of conflicting defaulted overloads the right one in a long chain of derivings.

How to find the usages of such defaulted overloads if there is a need to change the default, for example when a library from a different vendor must be used?
December 11, 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);
> 
> 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

Personally I just don't think I'd ever have a use for it...  Rare is the string literal in my code without a c|w|d suffix.  (Partially because I use Mango an awful lot, which does have a few cases of this ambiguity -- Stdout anyone?  But no problem... I never code Stdout("Hello!") but always Stdout("Hello!"c) instead... tada, problem solved with existing features.

But apparently a lot of people do see something useful about this.  So I abstain and vote neutral.  :)

-- Chris Nicholson-Sauls
December 11, 2006
Chris Nicholson-Sauls 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);
>>
>> 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
> 
> Personally I just don't think I'd ever have a use for it...  Rare is the string literal in my code without a c|w|d suffix.  (Partially because I use Mango an awful lot, which does have a few cases of this ambiguity -- Stdout anyone?  But no problem... I never code Stdout("Hello!") but always Stdout("Hello!"c) instead... tada, problem solved with existing features.
> 
> But apparently a lot of people do see something useful about this.  So I abstain and vote neutral.  :)
> 
> -- Chris Nicholson-Sauls

The Mango example is actually a perfect case for how this can trip programmers up.  But you're right, using existing features (as minimally intrusive as c/d/w) are the right way to go.

Still, I've often wondered if there wasn't a better way.  Something like  auto defining char data as UTF-8/16/32 based on the *source file encoding* might go a long way to make this a little more implicit. However, I'm not sure if that would be too subtle to maintain practically.

-- 
- EricAnderton at yahoo
December 11, 2006
On Mon, 11 Dec 2006 16:07:39 -0500, Pragma 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.

...

> Still, I've often wondered if there wasn't a better way.

Would it be possible for the compiler to encode an unqualified string literal based on a hierarchy of matches. In other words, if there exists a char[] match use that, otherwise if there exists a wchar[] match then use that, otherwise if there exists a dchar[] match use that else there is no match.

In Chris' original example the 'foo(char[])' would match and so the compiler encodes the literal as utf-8.

Thus is multiple matches are possible, the compiler chooses them in order of utf-8, utf-16, and utf-32. Thus if the coder explicitly wants a specific 'foo' to be called they would need to explicitly encode the literal with the c/w/d qualifier.

This idea seems reasonable and maybe also can be extended in concept to unqualified numeric literals.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
12/12/2006 9:19:36 AM
1 2
Next ›   Last »