April 01, 2004
Here is yet another idea for default/optional arguments for D. It might be what Manfred is talking about but since I quite can't figure out his proposal I'm filling in my interpretation. Apologies if this has already been proposed and I missed it.

The basic grammar change is to allow declarations after "...". In this case
an implicit parameter "va_num" (type int) is defined and assigned the number
of actual parameters supplied. Parameters that are omitted are given the
type's initial value. Also any supplied args must match the types of the
declarations.
For example

  void foo(int a, int b, ... char[] x, int y)
  {
    if (va_num < 1) x = "hello";
    if (va_num < 2) y = 42;
    // continue as normal
  }

 user code          compiler generates
foo(1,2)          foo(1,2,0,null array,0)
foo(1,2,"hi")     foo(1,2,1,"hi",0)
foo(1,2,"hi",3)   foo(1,2,2,"hi",3)
foo(1,2,"hi","a") error can't convert char[] to int

At the call site the compiler pushes onto the stack
1) the required arguments
2) the value for "va_num" followed by
3) the optional values the user passed (if any)
4) the type initializer values for the remaining arguments (if any)

In overload resolution and name mangling etc the signature of foo is treated the same as

  void foo(int a, int b, ... )

So if any two of the following are declared then the overloading logic throws an error

  void foo(int a, int b, ... char[] x, int y)
  void foo(int a, int b)
  void foo(int a, int b, ... int x)

This is keeping with D's style of avoiding ambiguities in calls like
  foo(1,2)
even though foo(1,2,"foo") could concievably be resolved to
  void foo(int a, int b, ... char[] x, int y)

There is no conflict with overridden methods since every call to foo pushes the same amount of stuff onto the stack and the types of what is on the stack is known at compile time. The actualy values are filled in by the function body. For example a subclass could define

  void foo(int a, int b,... char[] x, int y)
  {
    if (va_num < 1) x = "world";
    if (va_num < 2) y = 100;
    // continue as normal
  }

Downsides:
 - requires compiler change
 - setting defaults at runtime could be performance hit over having the call
site put the default value on the stack
 - overridden method has to repeat the defaults

Upside:
 - doesn't assign defaults at call site so is nice to overriding wanting
different defaults
 - less verbose than writing wrappers
 - compiler changes are small
 - extends the ... syntax and avoids confusion with C++ semantics and keeps
overloading rules


April 19, 2004
Ben Hinkle wrote:

[...]
>  user code          compiler generates
> foo(1,2)          foo(1,2,0,null array,0)
> foo(1,2,"hi")     foo(1,2,1,"hi",0)
> foo(1,2,"hi",3)   foo(1,2,2,"hi",3)
> foo(1,2,"hi","a") error can't convert char[] to int
[...]

This seems too much effort to me for something that already can be done.

So long!