On Mon, 27 Aug 2012 09:23:54 -0400, kenji hara <k.hara...@gmail.com> wrote:

I think that the function type and its mangled name must not contain
the default args, then I can agree with Walter at the point.

But, I think the variables of function pointers and delegates still
can have default args as a part of their declarations.
(It will be a part of VarDeclaration, not a part of TypeFunction)
In following case, the default arg looks like a part of the type, but
actually is a part of the declaration of fp.

I think the type of the function pointer and the type (and mangling) of the function are two separate types. One is a function pointer, one is a function.

You only need to mangle the function, not the pointer type.

Consider this rough equivalent (not sure how to write the constraints):

struct callWithN(F, int n) if(F is a function which takes an int as its last arg)
{
   F funcptr;
   auto opCall(T...)(T t) if(T is equivalent to F's args)
   {
      return funcptr(t);
   }
auto opCall(T...)(T t) if(T is equivalent to F's args, except for last int arg)
   {
      return funcptr(t, n);
   }
}

I think the above (with correct template constraints) is equivalent to defining a function pointer with a default integer argument. Note that the function it points to has *nothing* to do with default args, and so should be mangled like any other function.

So I think the default args have to be part of the pointer type, just not the function type.

void function(int n = 10) fp;
pragma(msg, typeof(fp));  // should print void function(int), because
default args are not a part of type.

No.  They are part of the function pointer type.

  // fp will *inherit* default args from its initializer, or not?
  auto fp = (int n = 10){}

Yes, this should be equivalent to:

void function(int = 10) fp = (int n){};

  // what is the actual default arg of fp?
  void function(int n = 10) fp1 = (int n = 20){}

compiler error. Even if it should be able to reassign a default arg 10 to a default arg 20 function pointer, allowing the above to compile would be extremely confusing, and there is no real reason to allow it. Use the property of the function pointer that gets the function pointer type without the default params (see below).

  void function(int n) fp2 = (int n = 30){}

30

  void function(int n = 40) fp3 = (int n){}

40


  // fp has ambiguous default arg, or has no default arg?
  auto fp1 = some_runtime_condition ? (int n = 10){} : (int n = 20){} ;

Compiler error. You can't define the type differently based on a runtime condition.

// more complicated case, first defarg is same, then it will be *inherited*?
  auto fp2 = some_runtime_condition ? (int n = 10, string s =
"hello"){} : (int n = 10, string s = "world"){} ;

Again, two different types.  Error.


int function(int n = 10) fp; // default arg of the first parameter is 10
  fp = (int n = 20){ return n; }  // function literal's default arg
will be ignored (in my opinion), is this expected?

I think actually, this should be a compiler error, but it would be a valid choice to make this simply ignore the secondary default arg.

Here is what I would like to happen:

Given two sets of default parameter tuples X and Y, where X is not a prefix of Y, and Y is not a prefix of X, a function pointer with default args X cannot be assigned from a function pointer with default args Y. Given X and Y where X is a prefix of Y, a function pointer with default args Y can be assigned from a function pointer with default args X. However, the opposite will not be true. However, we should define a function pointer property (e.g. funcptr) which gives naked access to the underlying function pointer.

So if you had fx with default args X, and fy with default args Y, and both pointed at functions with the same parameter types, then you could do:

fx.funcptr = fy.funcptr;
fy.funcptr = fx.funcptr;

If this is too complicated, then just allowing all functions with the same underlying function parameter types to be freely assignable also is a valid (but IMO more confusing) choice.

Given the above, I think it would be prudent to have the default args returnable via a property or a __traits command. e.g.:

auto tupleOfDefaultArgs = fx.defargs;


  // returning function pointer/delegate type can have default args?
  int delegate(int n = 10) foo(int x) { ... }

Of course.  Default args are part of the pointer type.

-Steve

Reply via email to