View mode: basic / threaded / horizontal-split · Log in · Help
April 26, 2012
Re: What to do about default function arguments
On 04/26/2012 11:54 AM, Don Clugston wrote:
> On 26/04/12 11:21, Timon Gehr wrote:
>> On 04/26/2012 09:54 AM, Walter Bright wrote:
>>> On 4/26/2012 12:47 AM, Timon Gehr wrote:
>>>> On 04/26/2012 05:44 AM, Walter Bright wrote:
>>>>> A subtle but nasty problem - are default arguments part of the
>>>>> type, or
>>>>> part of the declaration?
>>>>>
>>>>> See http://d.puremagic.com/issues/show_bug.cgi?id=3866
>>>>>
>>>>> Currently, they are both,
>>>>
>>>> That is how it should be.
>>>>
>>>>> which leads to the nasty behavior in the bug report.
>>>>>
>>>>
>>>> It contributes, but it is not the main cause.
>>>>
>>>>> The problem centers around name mangling. If two types mangle the
>>>>> same,
>>>>> then they are the same type.
>>>>
>>>> Then they are equal types.
>>>
>>> This is simply not tenable. What defines when they are "equal" types and
>>> when they are "not equal"?
>>
>> This is a matter of terminology. For example, for 'equal' just exclude
>> the default parameters from the comparison. For 'the same' include
>> default parameters in the comparison. (therefore, 'the same' implies
>> 'equal')
>
> The language doesn't have the concepts of "same" and "equal" with
> respect to types. There is "equal" and "implicitly converts to", but
> that's not quite the same.
>
>>>> The schizophrenic behavior occurs because the types cross-talk. Are
>>>> mangled
>>>> names kept unique in the compiler or what is the implementation issue
>>>> exactly?
>>>
>>> It's a conceptual issue. When is one type the same as another, and when
>>> is it not?
>>>
>>
>> void function(int) is the same as void function(int) and both are equal
>> void function(int=2) is not the same as void function(int=3), but both
>> are equal.
>
> The question was *when* are they same, not how you name them.

I think I have answered that. Anyway, probably it is indeed a good idea 
to get rid of default parameters for delegates and function pointers.
The issues are certainly resolvable but the complexity of the resulting 
feature could not be justified.
April 26, 2012
Re: What to do about default function arguments
On 26/04/12 12:11, Timon Gehr wrote:
> On 04/26/2012 11:46 AM, Don Clugston wrote:
>> On 26/04/12 11:28, Timon Gehr wrote:
>>> On 04/26/2012 10:51 AM, Don Clugston wrote:
>>>> On 26/04/12 05:44, Walter Bright wrote:
>>>>> A subtle but nasty problem - are default arguments part of the
>>>>> type, or
>>>>> part of the declaration?
>>>>>
>>>>> See http://d.puremagic.com/issues/show_bug.cgi?id=3866
>>>>>
>>>>> Currently, they are both, which leads to the nasty behavior in the bug
>>>>> report.
>>>>>
>>>>> The problem centers around name mangling. If two types mangle the
>>>>> same,
>>>>> then they are the same type. But default arguments are not part of the
>>>>> mangled string. Hence the schizophrenic behavior.
>>>>>
>>>>> But if we make default arguments solely a part of the function
>>>>> declaration, then function pointers (and delegates) cannot have
>>>>> default
>>>>> arguments. (And maybe this isn't a bad thing?)
>>>>
>>>> I think it is a mistake to allow default arguments in function pointers
>>>> and delegates (it's OK for delegate literals, there you have the
>>>> declaration).
>>>
>>> The parenthesised part is in conflict with your other statement.
>>
>> No it doesn't. A default argument is a delegate literal is part of the
>> declaration, not part of the type.
>
> If types cannot specify default arguments, then those will be thrown
> away right away, because what is later called is based on the type of
> the delegate and not on the implicit function declaration that has its
> address taken. What is the point of allowing it if it cannot be used?

Fair point. It could be used in the case where it is called at the point 
of declaration (I do that a fair bit), but it's pretty much useless 
because it is clearer code to put the default parameter in the call.

int m = (int a, int b = 3){ return a+b;}(7);

Point conceded. So default arguments should be disallowed in delegate 
literals as well.
April 26, 2012
Re: What to do about default function arguments
I've always thought of default arguments to be plain syntactic sugar, so  
for void f(int i, int j=5)    f(1) is simply transformed to f(1,5) and the  
rest is the same.
April 26, 2012
Re: What to do about default function arguments
On 2012-04-26 03:44:07 +0000, Walter Bright <newshound2@digitalmars.com> said:

> A subtle but nasty problem - are default arguments part of the type, or 
> part of the declaration?
> 
>     See http://d.puremagic.com/issues/show_bug.cgi?id=3866
> 
> Currently, they are both, which leads to the nasty behavior in the bug report.
> 
> The problem centers around name mangling. If two types mangle the same, 
> then they are the same type. But default arguments are not part of the 
> mangled string. Hence the schizophrenic behavior.
> 
> But if we make default arguments solely a part of the function 
> declaration, then function pointers (and delegates) cannot have default 
> arguments. (And maybe this isn't a bad thing?)

Assuming we want to allow it, all you need is to treat the type having 
the default parameters as a specialization of the type that has none. 
In other words, the type with the default arugments is implicitly 
castable to the type without.

Should it affect name mangling? Yes and not. It should affect name 
mangling in the compiler since you're using the mangled name to check 
for equality between types. But I think it should not affect name 
mangling for the generated code: the base type without the default 
arguments should give its name to the emitted symbols so that changing 
the default argument does not change the ABI.

But is it desirable? I'm not convinced. I don't really see the point. 
It looks like a poor substitute for overloading to me.

That said, there was some talk about adding support for named 
parameters a year ago. For named parameters, I think it'd make sense to 
have parameter names be part of the type, and little harm would result 
in adding default parameters too into the mix. As suggested above, it 
should be implicitly castable to a base type without parameter names or 
default values. But for default parameters alone, I don't feel the 
complication is justified.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
April 26, 2012
Re: What to do about default function arguments
Le 26/04/2012 05:44, Walter Bright a écrit :
> A subtle but nasty problem - are default arguments part of the type, or
> part of the declaration?
>
> See http://d.puremagic.com/issues/show_bug.cgi?id=3866
>
> Currently, they are both, which leads to the nasty behavior in the bug
> report.
>
> The problem centers around name mangling. If two types mangle the same,
> then they are the same type. But default arguments are not part of the
> mangled string. Hence the schizophrenic behavior.
>
> But if we make default arguments solely a part of the function
> declaration, then function pointers (and delegates) cannot have default
> arguments. (And maybe this isn't a bad thing?)

Maybe the problem is that type are considered to be the same when the 
mangling is the same. The default parameter is part of the type, isn't 
mangled (or hell will come on earth) and is covariant with the type with 
no default.
April 26, 2012
Re: What to do about default function arguments
Walter:
> A subtle but nasty problem - are default arguments part of the 
> type, or part of the declaration?

I'm waiting for years to see you finally facing this problem too 
:-) The current situation is not acceptable, so some change of 
the current situation is required, probably a small breaking 
change.

The simplest solution is to the breaking change of disallowing 
default arguments for function pointers and delegates. This also 
means disallowing talking the pointer/delegate of function with 
default arguments. The advantage of this solution is its 
simplicity, for both the compiler the D programmer and the D 
newbie that has to learn D.

A second alternative solution is to put the default arguments 
inside the function mangled and, and to avoid troubles, allow 
this only for POD data known at compile-time (and throw a 
compile-time error in all other cases). This has the advantage 
that common default arguments like "true", 15, 2.5, are accepted, 
so this gives some flexibility. One disadvantage is that you need 
to add a special case to D, but it's not a nasty special case, 
it's a clean thing.

A third possible way is to put the default arguments inside the 
delegate/function itself, as in Python. So default arguments for 
delegates/function have a different semantics. Then add a hidden 
extra field to such delegates/functions, a ubyte that tells the 
function how many arguments are actually given to the function 
(so the function is later able to use this argument to know how 
many arguments replace with the default ones). This has some 
disadvantages, because you can retrofit already compiled modules, 
so you can't get the function pointer of a function that doesn't 
have this hidden argument. The advantage is that the semantics is 
clean, and it's quite flexible.

Bye,
bearophile
April 26, 2012
Re: What to do about default function arguments
Michel Fortin:

> That said, there was some talk about adding support for named 
> parameters a year ago.

Good reminder. I think such parts of D shouldn't be designed one
of a time. If you want to face the problem of default arguments,
it's better to think about named arguments too (even if you don't
want to implement them now, to not preclude their good future
implementation).

Bye,
bearophile
April 26, 2012
Re: What to do about default function arguments
On Wed, 25 Apr 2012 23:44:07 -0400, Walter Bright  
<newshound2@digitalmars.com> wrote:

> A subtle but nasty problem - are default arguments part of the type, or  
> part of the declaration?
>
>     See http://d.puremagic.com/issues/show_bug.cgi?id=3866
>
> Currently, they are both, which leads to the nasty behavior in the bug  
> report.
>
> The problem centers around name mangling. If two types mangle the same,  
> then they are the same type. But default arguments are not part of the  
> mangled string. Hence the schizophrenic behavior.
>
> But if we make default arguments solely a part of the function  
> declaration, then function pointers (and delegates) cannot have default  
> arguments. (And maybe this isn't a bad thing?)

Some testing (2.059):

void main()
{
    auto a = (int x = 1) { return x;};
    auto b = (int x) { return x;};
    pragma(msg, typeof(a).stringof);
    pragma(msg, typeof(b).stringof);
}

output:

int function(int x = 1) pure nothrow @safe
int function(int x = 1) pure nothrow @safe

second pass:

void main()
{
    auto a = (int x = 1) { return x;};
    pure nothrow @safe int function(int) b = (int x) { return x;};
    pragma(msg, typeof(a).stringof);
    pragma(msg, typeof(b).stringof);
    b = a; // ok
    //a = b; // error

    //b(); // error
}

output:

int function(int x = 1) pure nothrow @safe
int function(int)


if you ask me, everything looks exactly as I'd expect, except the auto  
type inference of b.  Can this not be fixed?  I don't understand the  
difficulty.

BTW, I didn't know you could have default arguments for  
functions/delegates, it's pretty neat :)

-Steve
April 26, 2012
Re: What to do about default function arguments
On 26/04/12 05:44, Walter Bright wrote:
> But if we make default arguments solely a part of the function declaration, then
> function pointers (and delegates) cannot have default arguments. (And maybe this
> isn't a bad thing?)

I can't see disallowing default arguments as being a good thing.  For example, 
instead of,

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

surely I can just put instead

    void foo(int a, int b)
    {
        ...
    }

    void foo(int a)
    {
        foo(a, 2);
    }

... and surely I can do something similar for function pointers and delegates. 
So, I can still have default arguments in effect, I just have to work more as a 
programmer, using a less friendly and easy-to-understand syntax.  That doesn't 
really seem like a good way to operate unless there's an extreme level of 
complication in getting the compiler to handle the situation.
April 26, 2012
Re: What to do about default function arguments
On Thu, 26 Apr 2012 09:08:07 -0400, Steven Schveighoffer  
<schveiguy@yahoo.com> wrote:

> void main()
> {
>      auto a = (int x = 1) { return x;};
>      pure nothrow @safe int function(int) b = (int x) { return x;};
>      pragma(msg, typeof(a).stringof);
>      pragma(msg, typeof(b).stringof);
>      b = a; // ok
>      //a = b; // error
>
>      //b(); // error
> }
>
> output:
>
> int function(int x = 1) pure nothrow @safe
> int function(int)
>

Nevermind, I just realized it was ignoring my pure nothrow @safe for the  
declaration.  Moving it after the declaration results in:

void main()
{
    auto a = (int x = 1) { return x;};
    int function(int) pure nothrow @safe b = (int x) { return x;};
    pragma(msg, typeof(a).stringof);
    pragma(msg, typeof(b).stringof);
}

output:

int function(int x = 1) pure nothrow @safe
int function(int x = 1) pure nothrow @safe

which clearly mimics the auto behavior.  This is *really* no good, since  
it seems to be ignoring the explicit type that I specified.

IMO, the correct solution is to make the default argument part of the type  
(and don't let it affect things globally!), and make it derived from the  
version without a default arg.  I think Michel Fortin said the same thing.

-Steve
1 2 3 4 5
Top | Discussion index | About this forum | D home