This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Tail recursion and hobbit (was: finite state machines in guile)



The following program:

(define (fact n)
  (letrec ((fact2 (lambda (n f)
                    (if (<= n 1)
                        f
                        (fact2 (- n 1) (* f n))))))
    (fact2 n 1)))
  
is compiled by guile-hobbit-1.3 to C as:

#include "fact.h"

static SCM H_fact(n)
SCM n;
{
  return H_fact_fn1(n,SCM_MAKINUM(1));
}

static SCM H_fact_fn1(n__1,f)
SCM n__1,f;
{
  SCM tmp_var1,tmp_var2;

tailrecursion:
  if(n__1 <= SCM_MAKINUM(1))
    return f;
  else {
    tmp_var1 = SCM_MAKINUM(SCM_INUM(n__1) - 1);
    tmp_var2 = SCM_MAKINUM(SCM_INUM(f) * SCM_INUM(n__1));
    n__1 = tmp_var1;
    f = tmp_var2;
    goto tailrecursion;
  }
}

static SCM H_top_actions_fact()
{
  return scm_make_subr("fact",scm_tc7_subr_1,H_fact);
}

SCM scm_init_fact()
{
  protect_constants_fact = &SCM_CDR(intern("protect_constants_fact",22));
  {
    GLOBAL(protect_constants_fact) = SCM_EOL;
#ifdef HOBBIT_MODULE
    scm_variable_set_x(scm_eval_0str("(let ((v (module-variable (current-module) 'protect_constants_fact )))""  (if v v (module-make-local-var! (current-module) 'protect_constants_fact )))"),GLOBAL(protect_constants_fact));
#endif
  }
  H_top_actions_fact();
}

So hobbit DOES this kind of tail recursion optimization independently
from the underlying C compiler.

Mutually recursive calls (A calling B calling A calling B...) are not
supported for the moment.

--

B. Urban