bearophile wrote:
Time ago I have suggested here (and in the Python newsgroup) to have 
automatically defined inside a function a standard name like __func__ that's an 
alias of the recursive function name it's contained into, this helps avoid 
stating the name of the function two or more times (as the this() constructor 
of D), this keeps the code a little DRYer, so renaming or moving around a 
recursive function gets a bit simpler and cleaner.


Recursive functions have suggested me another little feature (that can not be added to 
Python because of its design) that I think I've not seen elsewhere. My recursive 
functions sometimes need to keep a bit of state, for example an integer that keeps the 
current "depth" of a tree structure that I'm creating or scanning, normally in 
D I can define the function like this:

/// Always use depth=0 at the first call
int foo1(int x, int depth=0) {
  ...
  foo1(x, depth + 1);
  ...
}

The last argument depth must be zero when the function is not called by itself, 
but I must rely on convention and code comments, because the program can't 
avoid errors like:

void main() {
  foo1(10, 5);
}

To be sure to avoid that error I can create a callable struct that keeps depth 
as an attribute (code not tested):

struct foo2 {
  int depth = 0;
  int opCall(int x) {
    ...
  }
}

This foo2 may even be a little faster because less data is passed to the 
function (callable struct) argument.

But another possible solution is to have private default function arguments:

int foo3(int x, private int depth=0) {
  ...
foo3(x+1); // OK foo3(x, depth + 1); // OK
  ...
}
void main() {
  int r = foo3(5); // OK
int r = foo3(5, 1); // Error int r = foo3(5, 0); // Error }

Now the programmer is allowed to give/specify the "depth" argument only inside 
foo() itself :-)
So the source code comment of foo1() is converted in foo3() into something that 
the compiler can enforce at compile-time.

Bye,
bearophile

There is another way that is idiomatic since C:

private void foo4_R(int x, int depth) {
    // ...
    foo4_R(x+1, 0);       // OK
    foo4_R(x, depth + 1); // OK
    // ...
}

void foo4(int x)
{
    foo4_R(x, 0);
}

Of course in C, the _R version would be file-local (i.e. static), instead of 'private'. And in C++, it would be in the anonymous namespace.

Ali

Reply via email to