Function pointers/delegates default args were stealth removed?

Carl Sturtivant sturtivant at gmail.com
Wed Aug 29 02:42:40 PDT 2012


On Tuesday, 28 August 2012 at 20:33:50 UTC, Carl Sturtivant wrote:
> On Monday, 27 August 2012 at 00:44:54 UTC, 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?
>>
>> 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. I.e. you lose the default argument information, 
>> since that is not attached to the type.
>
> I think this is the right behavior too. Default arguments are 
> IMHO just a compact way to write some simply related overloaded 
> functions, e.g. thus:
>
>   int sum(int x, int y = 1 ) { return x + y; }
>
> is just a compact way to write
>
>   int sum(int x, int y) { return x + y; }
>   int sum(int x) { return sum(x, 1); }
>
> and a function pointer refers to a single function, so 
> overloading and default arguments are irrelevant to function 
> pointers. It just so happens that the particularly simple 
> overloading abbreviated by a function definition with default 
> arguments is easily optimized by the compiler with only one 
> function arriving at the linker: the most general one. And 
> that's the one whose address is supplied if the unary & 
> operator is applied to it.
>
> So that's the problem with 'int sum(int x, int y = 1 ) ...' --- 
> it's not one function under the interpretation above. So how 
> could we interpret
>   int function(int x, int y = 1) sum;
> in the above interpretation? What's happening right now is that 
> sum is considered to be a single function pointer, so we 
> discard the default to get the most general function type much 
> like the effect of unary & above. So the trouble with the 
> supposed type 'int function(int x, int y = 1)' is that it is 
> not one type, just as the function sum above is not one 
> function.
>
> [Speculation mode starts here.] So what if function pointer 
> declarations with defaults are considered to define several 
> function pointers and not just one. e.g. thus:
>
>   int function(int x, int y = 1) sum;
>
> could be taken by the compiler to mean
>
>   int function(int x, int y) sum;
> //all the rest call back the general function pointer
>   int function(int x) sum = function sum(int x) { return 
> sum(x,1); }
>
> I haven't explored all of the ramifications of this, but it 
> looks as if it solves quite a few problems without changing the 
> type system, or affecting existing code. And there's a simple 
> model of what's going on: overloading, just generalized 
> slightly.
>
> This may not be clean enough or general enough. But the basic 
> point that something like 'int function(int x, int y = 1)' is a 
> sequence of types is worth attention. A declaration using a 
> sequence of types should produce a sequence of function 
> pointers under this interpretation. Exactly how "sequence of 
> types" and "sequence of pointers" should be wrapped up for best 
> effect is then the language design decision to make. There are 
> several other interesting ways to go, some involving getting 
> more general and allowing other kinds of overloading with 
> function pointer sequences, not just the special kind that 
> comes from default arguments, but I'll stop here for now.

Here is an additional implementation possibility for the minimal 
version where there are no new types. Parameters, e.g.:

void fun(int x, int function(int x, int y = 1) fun) {
//...
   j = fun(3); //alerts the compiler
//...
}

could be analogously compiled to behave similarly, because the 
default arguments are 'nearby'. Here's what the compiler could in 
effect produce from the above.

int fun(int x, int function(int x, int y) fun) {
   int function(int x) fun = function void(int x) { return fun(x, 
1); }
//...
   j = fun(3);
//...
}

i.e. use local variables for the required specialized versions of 
the function.

Of course then the question of "how near is nearby?" needs a 
design decision.




More information about the Digitalmars-d mailing list