June 13, 2006
Bruno Medeiros wrote:
> BCS wrote:
>> <code>
>> import std.stdio;
>>
>> class C        { int foo(int x = 1){return x;} }
>> class D:C    { int foo(int x = 2){return x;} }
>>
>>
>> void main()
>> {
>>     C c = new D;
>>     D d = cast(D)c;
>>
>>     writef(c.foo,\n);    // prints 1 (?)
>>     writef(d.foo,\n);    // prints 2
>> }
>> </code>
> 
> 
> Hum, quite a catch you got there! Not only should it be better documented, but maybe it shouldn't work this way.
> Perhaps the default values should be set not at the call site, but by the function itself (thus depending on it's run-time type, and not it's compile-time type), or maybe it could be as Oskar's idea ("if D inherited default values and forbade them to be redefined in derived classes")
> 
hee hee, their is one use for this


// never call with i set explicitly

class C { abstract void doSomthing(char[] msg, int i=0); }
class D:C { abstract void doSomthing(char[] msg, int i=1); }
class E:D { abstract void doSomthing(char[] msg, int i=2); }
class F:E { void doSomthing(char[] msg, int i=3)
{
	writef(`doSomthing("%s") as class %c`\n,msg, 'C'+i);
}
}

Now we known the type of the reference used to call doSomthing. (I pray I never have reason to use this.)
June 14, 2006
Bruno Medeiros wrote:
> BCS wrote:
>> Deewiant wrote:
>>> All I can find about default parameters in the spec is at the "Functions" page,
>>> where they pop out of the blue in the phrase "A function parameter's default
>>> value is not inherited", which is all that's said about them. The 
...
>>
> Hum, quite a catch you got there! Not only should it be better documented, but maybe it shouldn't work this way.
> Perhaps the default values should be set not at the call site, but by the function itself (thus depending on it's run-time type, and not it's compile-time type),

I'm almost certain that default values should work that way. They should just be syntactic sugar for overloaded functions.
Right now, they have the same problem which C++ has -- there's no way that a template can find out what the default values are, and the default values can't be used by function pointers or delegates.
So for example,

void foo(int a, int b=2, int c=3) {}

void goo(int a, int b, int c) { }
void goo(int a, int b) { goo(a, b, 3); }
void goo(int a) { goo(a, 2, 3); }

void function(int) boo;

foo(7); // ok
goo(7); // ok

boo = goo; // ok
boo(5);

boo = foo; // doesn't compile -- why not?
boo(5);


 or maybe it could be as Oskar's idea ("if D
> inherited default values and forbade them to be redefined in derived classes")

June 18, 2006
Don Clugston wrote:
> Bruno Medeiros wrote:
>> BCS wrote:
>>> Deewiant wrote:
>>>> All I can find about default parameters in the spec is at the "Functions" page,
>>>> where they pop out of the blue in the phrase "A function parameter's default
>>>> value is not inherited", which is all that's said about them. The 
> ....
>>>
>> Hum, quite a catch you got there! Not only should it be better documented, but maybe it shouldn't work this way.
>> Perhaps the default values should be set not at the call site, but by the function itself (thus depending on it's run-time type, and not it's compile-time type),
> 
> I'm almost certain that default values should work that way. They should just be syntactic sugar for overloaded functions.
> Right now, they have the same problem which C++ has -- there's no way that a template can find out what the default values are, and the default values can't be used by function pointers or delegates.
> So for example,
> 
> void foo(int a, int b=2, int c=3) {}
> 
> void goo(int a, int b, int c) { }
> void goo(int a, int b) { goo(a, b, 3); }
> void goo(int a) { goo(a, 2, 3); }
> 
> void function(int) boo;
> 
> foo(7); // ok
> goo(7); // ok
> 
> boo = goo; // ok
> boo(5);
> 
> boo = foo; // doesn't compile -- why not?
> boo(5);
> 
> 

You meant:
  boo = &goo; // ok
  boo(5);

  boo = &foo; // doesn't compile -- why not?


Anyway, "Why not?" ? How could that compile? Even with that syntatic sugar the problem would subsist: remember that the expression (&foo) has to be evaluable by itself, and if there are many overloads of foo there is no way (with that syntax at least) to choose the correct one. (DMD currently chooses the lexically first overload)


-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
June 23, 2006
Bruno Medeiros wrote:
> Don Clugston wrote:
>> Bruno Medeiros wrote:
>>> BCS wrote:
>>>> Deewiant wrote:
>>>>> All I can find about default parameters in the spec is at the "Functions" page,
>>>>> where they pop out of the blue in the phrase "A function parameter's default
>>>>> value is not inherited", which is all that's said about them. The 
>> ....
>>>>
>>> Hum, quite a catch you got there! Not only should it be better documented, but maybe it shouldn't work this way.
>>> Perhaps the default values should be set not at the call site, but by the function itself (thus depending on it's run-time type, and not it's compile-time type),
>>
>> I'm almost certain that default values should work that way. They should just be syntactic sugar for overloaded functions.
>> Right now, they have the same problem which C++ has -- there's no way that a template can find out what the default values are, and the default values can't be used by function pointers or delegates.
>> So for example,
>>
>> void foo(int a, int b=2, int c=3) {}
>>
>> void goo(int a, int b, int c) { }
>> void goo(int a, int b) { goo(a, b, 3); }
>> void goo(int a) { goo(a, 2, 3); }
>>
>> void function(int) boo;
>>
>> foo(7); // ok
>> goo(7); // ok
>>
>> boo = goo; // ok
>> boo(5);
>>
>> boo = foo; // doesn't compile -- why not?
>> boo(5);
>>
>>
> 
> You meant:
>   boo = &goo; // ok
>   boo(5);
> 
>   boo = &foo; // doesn't compile -- why not?
> 
> 
> Anyway, "Why not?" ? How could that compile? Even with that syntatic sugar the problem would subsist: remember that the expression (&foo) has to be evaluable by itself, and if there are many overloads of foo there is no way (with that syntax at least) to choose the correct one. (DMD currently chooses the lexically first overload)

But the 'goo' example does compile. Why is there a difference between 'goo' and 'foo'?
AFAIK, default parameters were introduced (in C++) purely as syntactic sugar, and AFAIK they are only ever used in that way. I think they should be just syntactic sugar. As they exist in both D and C++, they are a quirky language primitive which cannot be emulated in any other way. They lead to some horrible corner cases.
June 23, 2006
Don Clugston wrote:
> Bruno Medeiros wrote:
>> Don Clugston wrote:
>>> Bruno Medeiros wrote:
>>>> BCS wrote:
>>>>> Deewiant wrote:
>>>>>> All I can find about default parameters in the spec is at the "Functions" page,
>>>>>> where they pop out of the blue in the phrase "A function parameter's default
>>>>>> value is not inherited", which is all that's said about them. The 
>>> ....
>>>>>
>>>> Hum, quite a catch you got there! Not only should it be better documented, but maybe it shouldn't work this way.
>>>> Perhaps the default values should be set not at the call site, but by the function itself (thus depending on it's run-time type, and not it's compile-time type),
>>>
>>> I'm almost certain that default values should work that way. They should just be syntactic sugar for overloaded functions.
>>> Right now, they have the same problem which C++ has -- there's no way that a template can find out what the default values are, and the default values can't be used by function pointers or delegates.
>>> So for example,
>>>
>>> void foo(int a, int b=2, int c=3) {}
>>>
>>> void goo(int a, int b, int c) { }
>>> void goo(int a, int b) { goo(a, b, 3); }
>>> void goo(int a) { goo(a, 2, 3); }
>>>
>>> void function(int) boo;
>>>
>>> foo(7); // ok
>>> goo(7); // ok
>>>
>>> boo = goo; // ok
>>> boo(5);
>>>
>>> boo = foo; // doesn't compile -- why not?
>>> boo(5);
>>>
>>>
>>
>> You meant:
>>   boo = &goo; // ok
>>   boo(5);
>>
>>   boo = &foo; // doesn't compile -- why not?
>>
>>
>> Anyway, "Why not?" ? How could that compile? Even with that syntatic sugar the problem would subsist: remember that the expression (&foo) has to be evaluable by itself, and if there are many overloads of foo there is no way (with that syntax at least) to choose the correct one. (DMD currently chooses the lexically first overload)
> 
> But the 'goo' example does compile. Why is there a difference between 'goo' and 'foo'?

What I was trying to say, in the general sense, is that by making default parameters be just sugar for function overloads, we become susceptible to the problems of ambiguous homonymous function overloads (which in fact, is a separate issue, and the one I was more worried about)
I'm not saying default parameters shouldn't be syntactic sugar because of that, I'm just pointing it out.


As for the ambiguous overloads issue: in the example above, I said "DMD currently chooses the lexically first overload" but that is not entirely correct. If that was so, then:

  boo = &goo; // ok

would not work as in the example above, yet it does. This can only be an ugly special case hack, and a huge breach of consistency, since the following doesn't work:

  (&goo) (1, 2); // Expected func with 2 params

  auto temp = &goo;
  boo = temp; // Type mismatch, expected void function(int)

This worries me.

> AFAIK, default parameters were introduced (in C++) purely as syntactic sugar, and AFAIK they are only ever used in that way. I think they should be just syntactic sugar. As they exist in both D and C++, they are a quirky language primitive which cannot be emulated in any other way. They lead to some horrible corner cases.

Yes, like that problem with overloading default parameters.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
June 23, 2006
Bruno Medeiros wrote:
> Don Clugston wrote:
> 
>> Bruno Medeiros wrote:
>>
>>
>> I'm almost certain that default values should work that way. They should just be syntactic sugar for overloaded functions.
>> Right now, they have the same problem which C++ has -- there's no way that a template can find out what the default values are, and the default values can't be used by function pointers or delegates.
>> So for example,
>>
>> void foo(int a, int b=2, int c=3) {}
>>
>> void goo(int a, int b, int c) { }
>> void goo(int a, int b) { goo(a, b, 3); }
>> void goo(int a) { goo(a, 2, 3); }
>>
>> void function(int) boo;
>>
>> foo(7); // ok
>> goo(7); // ok
>>
>> boo = goo; // ok
>> boo(5);
>>
>> boo = foo; // doesn't compile -- why not?
>> boo(5);
>>
>>
> 
> You meant:
>   boo = &goo; // ok
>   boo(5);
> 
>   boo = &foo; // doesn't compile -- why not?
> 
> 
> Anyway, "Why not?" ? How could that compile? Even with that syntatic sugar the problem would subsist: remember that the expression (&foo) has to be evaluable by itself, and if there are many overloads of foo there is no way (with that syntax at least) to choose the correct one. (DMD currently chooses the lexically first overload)
> 
> 

Things get worse when auto is used. you end up with a type that is indeterminable without knowing the lexical order of function decelerations. I that case code validity is dependent on the order of other code.


int foo(long i, int j){return i+j;}
char[] foo(int i){return i;}


auto fp = &foo;

auto i = foo(0,0);	// legal unless foo's are reversed

What is need is a way to specify a particular function as a pointer.

auto fp1 = &foo(int);
auto fp2 = &foo(long,int);	// function don't run
assert(fp1 != fp2);
1 2
Next ›   Last »