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.