Simple trampoline code
Ellery Newcomer
ellery-newcomer at utulsa.edu
Thu Jun 11 19:28:41 PDT 2009
bearophile wrote:
> I'm trying to convert to D2 the following (quite simplified up) Python code, that implements a trampoline to run tail-call functions with no stack overflow:
>
> # Python code
> # *args means almost all the arguments
> def trampoline(fun, *args):
> thunk = lambda : fun(*args)
> while True:
> (thunk, result) = thunk()
> if thunk is None:
> return result
>
> # a tail-recursive function
> def summer(n, p = 1):
> if n >= 2:
> return (lambda n=n, p=p: summer(n-1, n+p), None)
> else:
> return (None, p)
>
> assert trampoline(summer, 1000) == 500500
>
>
> My D2 version so far (doesn't work):
>
> // D2 + Phobos2 code
> import std.typecons: tuple;
> import std.stdio: writeln;
>
> int trampoline(TyFun, TyTuple)(TyFun fun, TyTuple args) {
> auto thunk = { fun(args.tupleof) };
> while (true) {
> auto pair = thunk();
> thunk = pair.field[0];
> auto result = pair.field[1];
> if (thunk is null)
> return result;
> }
> }
>
> auto summer(int n, int p=1) {
> if (n >= 2)
> return tuple((int n=n, int p=p){return summer(n-1, n+p);}, 0);
> else
> return tuple(null, p);
> }
>
> void main() {
> writeln(trampoline(summer, tuple(1000)));
> }
>
> The D2 compiler outputs:
> trampoline.d(18): Error: forward reference to inferred return type of function call summer(n - 1,n + p)
> Can that D2 code be fixed?
>
> Bye,
> bearophile
How DO you define the signature of a function that returns itself?
And FYI, dmd handles your particular example recursively just fine. But
you probably know that.
That aside, this is about the best that I can get:
int trampoline (TyFun, TyTuple) (TyFun fun, TyTuple targs){
while (1){
auto pair = fun(targs.tupleof[0..2]);
fun = pair.field[0];
int result = pair.field[1];
targs = tuple(pair.tupleof[2..4]);
if(fun is null){
return result;
}
}
}
class Durr{
alias summer opCall;
Tuple!(Durr,int,int,int) summer(int n, int p){
if (n>= 2){
return tuple(this,0,n-1,n+p);
}else return tuple(cast(Durr)null,p,0,0);
}
}
More information about the Digitalmars-d-learn
mailing list