Private default function arguments
Daniel Murphy
yebbliesnospam at gmail.com
Fri Jan 15 01:52:19 PST 2010
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
You could accomplish something similar by using a private type as the second parameter.
eg
private struct privateint { int i; alias i this; };
void foo(int x, privateint y = privateint(0))
{
...
}
It's ugly, but should give reasonable error messages.
More information about the Digitalmars-d
mailing list