August 27, 2012
On 8/27/2012 1:01 AM, Paulo Pinto wrote:
> For it sounds like constraining the language while keeping the C/C++ linker
> semantics, instead of using a D aware linker.

That's just one of the problems. And no, we can't go write our own linker on all platforms.


August 27, 2012
On 8/27/2012 1:10 AM, Manu wrote:
> I don't see how the linker enters into it. Default args are irrelevant to the
> linker.

Consider name mangling and what it's for. Now consider two *different* types mangling to the same name.

D fundamentally depends on a 1:1 correspondence between types and name mangling, not 1:n or n:1.
August 27, 2012
On Monday, August 27, 2012 08:14:41 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).

Default args are essentially copy-pasted at the call point. It makes no sense for them to be part of the type, and it makes no sense to use them with function pointers or function literals.

- Jonathan M Davis
August 27, 2012
On 8/27/2012 1:08 AM, Manu wrote:
> 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.

It was probably reduced from a larger scenario. Reduced bugs usually look pretty twisted.

> 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).

Because the two types were considered to be the same, only different.

----------------------------------

Please post a canonical example of how you use this, so we can think of an alternative.
August 27, 2012
>
> 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.

The following has other pervasive ramifications, to say the least. Worth thinking about IMHO nevertheless, even if to eventually say "no". So here's a completely different way that the effect of default arguments can be obtained without messing with the type system.

Suppose a function pointer is always permitted be called with fewer actual arguments than parameters declared. I'm speculating uncritically here, so bear with me; this could be restricted to calling function pointers & delegate pointers, or with an avalanche of consequences permitted also for direct function calling where it will interact with the overloading rules, or ... there are many possible arrangements. So let's forge ahead for now with the basic idea for function pointers.

Suppose a function pointer can be called with fewer actual arguments than the number of parameters in its declaration. Suppose that when such a call is made, the missing arguments will always be assigned the default initialization for their types (default default-arguments!). Now suppose that a language mechanism is provided so that code in the function body can determine how many actual arguments were supplied at the point of call.

Now any function pointer can simulate other default arguments (non-default default arguments) by testing the actual number of arguments supplied and assigning defaults overtly to the remainder inside the function body. No need for new types: this is a run-time action.

Now you can stamp on this with big logic boots, but let's see if I can escape from some of the trampling!

August 27, 2012
On 27 August 2012 11:12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

>
> and it makes no sense to use them with function pointers or function literals.
>

If that were true, we wouldn't be having this discussion.


August 27, 2012
2012/8/27 Walter Bright <newshound2@digitalmars.com>:
> 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.

For linker these types should be identical, so there shouldn't be any collisions, unless D handles default args fundamentally different than C++.

-- 
闇に隠れた黒い力
弱い心を操る
August 27, 2012
On 08/27/2012 05:05 AM, Walter Bright wrote:
> On 8/26/2012 6:55 PM, Timon Gehr wrote:
>> On 08/27/2012 02:44 AM, Walter Bright wrote:
>>> On 8/26/2012 4:50 PM, Timon Gehr wrote:
>>>> On 08/27/2012 12:41 AM, Walter Bright wrote:
>>>>>
>>>>> The trouble for function pointers, is that any default args would need
>>>>> to be part of the type, not the declaration.
>>>>>
>>>>
>>>> They could be made part of the variable declaration.
>>>
>>> You mean part of the function pointer variable?
>>>
>>
>> Yes.
>>
>>> Consider what you do with a function pointer - you pass it to someone
>>> else. That someone else gets it as a type, not a declaration.
>>
>> If it is a template function, yes. But then you may as well pass the
>> function pointer variable per alias, which is common.
>
> You pass the function declaration by alias, not the function pointer
> declaration. In which case you will get the default arguments.
>

The function declaration is not necessarily available and the
pointer/delegate might not be a constant. This is the point of function
pointers and delegates.

>>
>> Otherwise someone else gets nothing but a parameter declaration.
>>
>>> I.e. you lose the default argument information, since that is not
>>> attached to the
>>> type.
>>>
>>
>> I think most valid existing use cases would still be supported:
>>
>> int execFunctionPointer(int function(int = 2) fun){
>>      return fun();
>> }
>>
>> auto dg = (int x, int y=2){ return x+y; }
>> writeln(range.map!dg());
>>
>> int function(int=3)[] funs;
>> funs[0]();
>>
>> It is up to you if it is worth the effort, of course.
>
> and it falls apart immediately once you try to transfer that function
> pointer anywhere.
>

No it does not. The examples people have posted where it breaks their
code that I am aware of all would work with this scheme.

What possible use case do you think would have to be supported by
function pointer/delegate default arguments that cannot be supported
without serious implementation problems?

August 27, 2012
> Suppose a function pointer can be called with fewer actual arguments than the number of parameters in its declaration. Suppose that when such a call is made, the missing arguments will always be assigned the default initialization for their types (default default-arguments!). Now suppose that a language mechanism is provided so that code in the function body can determine how many actual arguments were supplied at the point of call.
>
> Now any function pointer can simulate other default arguments (non-default default arguments) by testing the actual number of arguments supplied and assigning defaults overtly to the remainder inside the function body. No need for new types: this is a run-time action.

That's a great idea Carl! You mean something like this:

int sum(int a, int b) {
  if( argc == 1 ) b = 1; //default for b if not supplied

  return a + b;
}

//...

auto f = &sum;

//...

auto x = sum(y);  //function pointer call, so fewer args permitted


August 27, 2012
On Monday, 27 August 2012 at 08:26:15 UTC, Jonathan M Davis wrote:
> On Monday, August 27, 2012 08:14:41 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).
>
> Default args are essentially copy-pasted at the call point. It makes no sense
> for them to be part of the type, and it makes no sense to use them with
> function pointers or function literals.

Agreed. So see my way of simulating these at run-time without adverse type consequences or any overhead for existing functions.