inner functions calling each other - how to do this with inner struct?
Ivan Kazmenko via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Feb 3 06:01:24 PST 2016
Hi,
1. What works.
Inside a function (outerFun), I've got inner functions fun1 and
fun2 which have to recursively call each other. Just writing
them one after the other does not work. I've managed to find a
trick to make it work though, which is to add empty compile-time
parameters to fun1 and fun2:
-----
import std.stdio;
void outerFun () {
void fun1 () (int x) {
writeln (x);
if (x > 0) fun2 (x - 1);
}
void fun2 () (int y) {
writeln (y);
if (y > 1) fun1 (y - 2);
}
fun2 (10);
}
void main () {outerFun ();}
-----
2. What doesn't work.
Next, I'd like to have an inner function fun1 and an inner struct
S with a method fun2, and an instance s of struct S. I want to
be able to call s.fun2 from fun1 and fun1 back from s.fun2. Now,
I can't figure out how to do that. The same trick does not seem
to work:
-----
import std.stdio;
void outerFun () {
struct S () {
void fun2 (int x) {
writeln (x);
if (x > 0) fun1 !() (x - 1);
}
}
S !() s;
void fun1 () (int y) {
writeln (y);
if (y > 1) s.fun2 (y - 2);
}
fun1 (10);
}
void main () {outerFun ();}
-----
Here are the errors I get:
-----
test2.d(7): Error: template instance fun1!() template 'fun1' is
not defined, did
you mean fun2?
test2.d(11): Error: template instance test2.outerFun.S!() error
instantiating
-----
So, is this mutual recursion (inner function and method of a
fixed instance of an inner struct) possible? This does not seem
theoretically wrong: we have to maintain exactly one outer
context pointer (to outerFun's current stack frame) for each
recursive call.
3. What also doesn't work.
Here is another attempt, where the outer scope is a struct, not a
function. Again, I want to be able to call fun1 from s.fun2 and
s.fun2 from fun1.
-----
import std.stdio;
struct outerStruct {
struct S {
void fun2 (int x) {
writeln (x);
if (x > 0) fun1 (x - 1);
}
}
S s;
void fun1 (int y) {
writeln (y);
if (y > 1) s.fun2 (y - 2);
}
}
void main () {outerStruct os; os.fun1 (10);}
-----
With no compile-time parameters, this just says:
-----
test3.d(7): Error: this for fun1 needs to be type outerStruct not
type S
-----
Apparently, the call to fun1 is not able to get the context
pointer to outerStruct os and use it to call fun1. Again, I
don't see a theoretical limitation here. Did I fail to express
my intent to the compiler, or is what I want impossible with the
current implementation?
4. Module scope.
At module scope (no outer context pointer needed), everything
works fine without the need for tricks:
-----
import std.stdio;
struct S {
void fun2 (int x) {
writeln (x);
if (x > 0) fun1 (x - 1);
}
}
S s;
void fun1 (int y) {
writeln (y);
if (y > 1) s.fun2 (y - 2);
}
void main () {fun1 (10);}
-----
Ivan Kazmenko.
More information about the Digitalmars-d-learn
mailing list