August 27, 2012
If I may, here's my suggestion on how everything could work (and I think should be doable) ... basically, it would be part of the type, but functions with the same parameters regardless of defaults would be implicitly convertible to one another:

------

void efpBad( int function(int) fun ) {
    return fun(); // Fails to compile, as expected
}

void efp1( int function(int) fun ) {
    return fun(1); // Compiles fine, works as expected
}

void efp1Def1( int function(int = 1) fun ) {
    return fun(); // Compiles fine, equivalent to fun(1) which should be expected
}


auto fn1p = (int x) { return x; };
auto fn1pDef = (int x = 2) { return x; };

auto fn2p = (int x, int y) { return x + y; };
auto fn2pDef = (int x, int y = 2) { return x + y; };


efp2(fn2p); // Fails to compile, obviously ... # of parameters don't match.
efp2(fn2pDef); // Fails to compile, # of parameters don't match (even though 1 has provided a "default")
efp2(fn1p); // Success ... returns 1 as expected
efp2(fn1pDef); // Ditto
efp3(fn1p); // Compiles ... implicitly convertible, returns 1 (efp3 is providing the default above)
efp3(fn1pDef); // Successfully compiles, returns 1 ... NOT 5 (because 1 is provided as the default in efp3 above)

// Implicitly convertible between variables
fn1p = fn1pDef; // Perfectly fine
fn1p(); // Fails to compile, must provide an argument!
fn1pDef = fn1p; // Again, fine. fn1pDef will allow the arg to have the default of 1 now.
fn1pDef(); // Succeeds, returns 1

fn1p = fn2pDef; // Fails to compile, as expected
fn1p = fn2p; // Nonsense, so it fails, of course

// IsExpressions
is(typeof(fn1p) == typeof(fn1pDef)); // False
is(typeof(fn1p) : typeof(fn1pDef));  // True
is(typeof(fn1pDef) : typeof(fn1p));  // True

I hope that was rigorous enough to show the behavior when passing around and such. I feel like this behavior would be acceptable for almost every use. I'm pretty sure this is how people were expecting it to behave before, anyway.

Is there a problem with it working this way? (Obviously, I'm no compiler expert)
August 27, 2012
On 8/26/2012 8:49 PM, Chris Cain wrote:
> If I may, here's my suggestion on how everything could work (and I think should
> be doable) ... basically, it would be part of the type, but functions with the
> same parameters regardless of defaults would be implicitly convertible to one
> another:

What happens with the name mangling? What about overloading? template type deduction? type specialization? type equivalence? type covariance?
August 27, 2012
On Monday, 27 August 2012 at 04:01:10 UTC, Walter Bright wrote:
> What happens with the name mangling? What about overloading? template type deduction? type specialization? type equivalence? type covariance?

Name mangling: Without knowing enough about compiler making, I'm not sure why it matters. I couldn't answer, sorry.

Overloading: I'm making a guess, but do you mean something like this?
void fn( int function(int) fp ) { ... }
void fn( int function(int = 1) fp ) { ... }

It should fail to compile.

Type specialization: Templates?
Bar!( int function(int) ) would have to be different than Bar!( int function(int = 1) ), I would think.

Template type deduction: I don't really understand the question with this, actually.

Type equivalence, type covariance: Like the is expressions I showed before? Or what do you mean? They should be implicitly convertible between each other.


I'm just giving you the standpoint of a user of the language, not necessarily a compiler writer (I have an extremely basic understanding of compilers ... mostly, I just know lexing and parsing at the moment), so I'm having difficulty understanding what some of the problems with this is.
August 27, 2012
On 8/26/2012 9:25 PM, Chris Cain wrote:
> On Monday, 27 August 2012 at 04:01:10 UTC, Walter Bright wrote:
>> What happens with the name mangling? What about overloading? template type
>> deduction? type specialization? type equivalence? type covariance?
>
> Name mangling: Without knowing enough about compiler making, I'm not sure why it
> matters. I couldn't answer, sorry.

The mangled names have a 1:1 correspondence with types. A mangled name can, for example, be reversed into a type.

If default args form part of the type, then they'll have to be mangled in, too. This causes a rather long list of substantial problems.
August 27, 2012
2012/8/27 Walter Bright <newshound2@digitalmars.com>:
> On 8/26/2012 9:25 PM, Chris Cain wrote:
>>
>> On Monday, 27 August 2012 at 04:01:10 UTC, Walter Bright wrote:
>>>
>>> What happens with the name mangling? What about overloading? template
>>> type
>>> deduction? type specialization? type equivalence? type covariance?
>>
>>
>> Name mangling: Without knowing enough about compiler making, I'm not sure
>> why it
>> matters. I couldn't answer, sorry.
>
>
> The mangled names have a 1:1 correspondence with types. A mangled name can, for example, be reversed into a type.
>
> If default args form part of the type, then they'll have to be mangled in, too. This causes a rather long list of substantial problems.

Default args should be part of types (for passing them as template args etc, implicity convertable if they differs only on defaults) but not mangled in (since mangling is revelant only for linking, where defaults doesn't matter).

-- 
闇に隠れた黒い力
弱い心を操る
August 27, 2012
On 27 August 2012 07:52, Walter Bright <newshound2@digitalmars.com> wrote:

> On 8/26/2012 9:25 PM, Chris Cain wrote:
>
>> On Monday, 27 August 2012 at 04:01:10 UTC, Walter Bright wrote:
>>
>>> What happens with the name mangling? What about overloading? template
>>> type
>>> deduction? type specialization? type equivalence? type covariance?
>>>
>>
>> Name mangling: Without knowing enough about compiler making, I'm not sure
>> why it
>> matters. I couldn't answer, sorry.
>>
>
> The mangled names have a 1:1 correspondence with types. A mangled name can, for example, be reversed into a type.
>
> If default args form part of the type, then they'll have to be mangled in, too. This causes a rather long list of substantial problems.
>

This sounds like an implementation detail/dmd quirk is defining the
language spec...
I generally agree with the usage proposal above, it should be metadata that
doesn't affect type equivalence (although I'd probably expect is(f1 ==
f2def) should be true rather than false).
If that info needs to be mangled into the name to reproduce the type later,
fine, is that a problem? Perhaps stick it at the end of the mangled name in
a new metadata suffix that is truncated prior to any comparisons for
equality?

This actually rather relates to the attribute/annotation proposals/conversations we were having some time back. If this is addressed, then it may enable attributes too.


August 27, 2012
On Monday, 27 August 2012 at 07:54:12 UTC, Manu wrote:
> On 27 August 2012 07:52, Walter Bright <newshound2@digitalmars.com> wrote:
>
>> On 8/26/2012 9:25 PM, Chris Cain wrote:
>>
>>> On Monday, 27 August 2012 at 04:01:10 UTC, Walter Bright wrote:
>>>
>>>> What happens with the name mangling? What about overloading? template
>>>> type
>>>> deduction? type specialization? type equivalence? type covariance?
>>>>
>>>
>>> Name mangling: Without knowing enough about compiler making, I'm not sure
>>> why it
>>> matters. I couldn't answer, sorry.
>>>
>>
>> The mangled names have a 1:1 correspondence with types. A mangled name
>> can, for example, be reversed into a type.
>>
>> If default args form part of the type, then they'll have to be mangled in,
>> too. This causes a rather long list of substantial problems.
>>
>
> This sounds like an implementation detail/dmd quirk is defining the
> language spec...

For it sounds like constraining the language while keeping the C/C++ linker semantics, instead of using a D aware linker.

Not trolling, just trying to understand the design constraints.

--
Paulo
August 27, 2012
On 27 August 2012 03:51, Walter Bright <newshound2@digitalmars.com> wrote:

> On 8/26/2012 5:06 PM, Manu wrote:
>
>> type that is technically equivalent, but foo's type would have the bonus default
>
> arg in its type record, just as a function pointer that were declared
>> explicitly.
>>
>
> That's the way it used to work. The problem is, what are those types? Are they the same types or not? You're saying sometimes they are the same type, sometimes they are not. It's a mess.


They are always equivalent. The default args are more like metadata.


At what point does the compiler become confused? They never interact... The
>> expected behaviour seems obvious to me, foo and bar should effectively be:
>>     int function(int a = 1) foo = ..;
>>     int function(int a) bar = ...;
>>
>
> It seems obvious only in the trivial case. What if you passed foo to a function? Now what type is it? What is the mangling for the type?


Well the function you pass foo to will define the type is receives.
If it receives by template, then it'll receive the default args, if it
defines the function pointer type it receives explicitly (or uses another
compatible definition), the default args may be lost (or different) in the
new instance across the function call.

I don't see why it needs to be mangled in. The linker doesn't care.


    The trouble for function pointers, is that any default args would need
>> to be
>>     part of the type, not the declaration.
>>
>>
>> I thought they were part of the type already? I would have thought that's
>> where
>> they should be. Why is their new home more 'proper'?
>>
>
> Because are the types the same or not?
>

They're equivalent, but not identical; one has some metadata the other doesn't have.


    I know it broke code (for many others, too), and I'm very sorry about
>> that,
>>     but I don't see another way out.
>>
>>
>> It's a rather major breakage. I've seen you reject far more important
>> changes
>> solely on the grounds that they are a breaking change before...
>>
>
> Unfortunately, it was already broken, as the bug report showed. It's a matter of where the crack shows up.
>

Does the bug report actually demonstrate how it was causing anybody any
problems? It seemed a rather contrived scenario that just illustrated that
there was a bug.
Also, I think it could be fixed so the scenario in the bug report worked as
expected (I still don't understand why it did't work in the first place).


August 27, 2012
On 27 August 2012 11:01, Paulo Pinto <pjmlp@progtools.org> wrote:

> On Monday, 27 August 2012 at 07:54:12 UTC, Manu wrote:
>
>>
>> This sounds like an implementation detail/dmd quirk is defining the language spec...
>>
>
> For it sounds like constraining the language while keeping the C/C++ linker semantics, instead of using a D aware linker.
>

I don't see how the linker enters into it. Default args are irrelevant to the linker.


August 27, 2012
On 8/26/2012 11:14 PM, Piotr Duda wrote:
> Default args should be part of types (for passing them as template
> args etc, implicity convertable if they differs only on defaults) but
> not mangled in (since mangling is revelant only for linking, where
> defaults doesn't matter).

And then there's a list of other bugs that show up. Now you have two different types showing up as the same type (i.e. name) to the linker, and you've got weird collisions.

Really, a type that is the same only different is a recipe for endless subtle and ugly problems. It's a nightmare.