Mutually Dependent Function Declarations in Functions

157 views Asked by At

Is it possible to have two or more outer function-scoped functions that have mutual call dependencies on each other?

I'm asking because

void main(string args[]) {
    int x = 42;
    void a() {
        // do something with x
        b();
    }
    void b() {
        // do something with x
        a();
    }
}

errors in DMD as

/home/per/Work/justd/t_funs.d(5): Error: undefined identifier b

If not is this an unresolved issue or a feature?

3

There are 3 answers

0
ratchet freak On BEST ANSWER

you can declare the delegate b before a and then assign b

void main(string args[]) {
    int x = 42;
    void delegate() b;
    void a() {
        // do something with x
        b();
    }
    b = delegate void () {
        // do something with x
        a();
    };
}

it'll require a refactor but not as bad as throwing it all in structs

0
Idan Arye On

Let's say you could. Then you could do:

void main(string args[]) {
    void a() {
        b();
    }
    a();
    int x = 42;
    void b() {
        // do something with x
        a();
    }
}

And viola - you use x before declaring it.

There are workarounds to that - like ratchet freak said you could use a delegate, but you could also use a struct:

void main(){
    int x=5;
    struct S{
        void a(){
            writefln("in a, x=%d",x);
            --x;
            if(0<x){
                b();
            }
        }
        void b(){
            writefln("in b, x=%d",x);
            --x;
            if(0<x){
                a();
            }
        }
    }
    S().a();
}

Notice that both solutions prevent using x before it's declaration. If you use a delegate you can't call it before you assign a function to it, which you can only do after you declare the other function, which happens after you declare x. If you use a struct you can't declare x either before of in the struct - but you can only call the functions after the struct is declared - which also means after x is declared.

1
Trass3r On

That's by design: "Unlike module level declarations, declarations within function scope are processed in order." (http://dlang.org/function.html#variadicnested)

Don't know the rationale though.