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.