| |
 | Posted by Ivan Kazmenko | Permalink Reply |
|
Ivan Kazmenko 
| 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.
|