All of MzScheme's built-in functions and syntax support proper tail-recursion. When a new primitive procedure or syntax is added to MzScheme, special care must be taken to ensure that tail recursion is handled properly. Specifically, when the final return value of a function is the result of an application, then scheme_tail_apply should be used instead of scheme_apply. When scheme_tail_apply is called, it postpones the procedure application until control returns to the Scheme evaluation loop.
For example, consider the following implementation of a thunk-or primitive, which takes any number of thunks and performs or on the results of the thunks, evaluating only as many thunks as necessary.
static Scheme_Object * thunk_or (int argc, Scheme_Object **argv) { int i; Scheme_Object *v; if (!argc) return scheme_false; for (i = 0; i < argc - 1; i++) if (SCHEME_FALSEP((v = _scheme_apply(argv[i], 0, NULL)))) return v; return scheme_tail_apply(argv[argc - 1], 0, NULL); }
This thunk-or properly implements tail-recursion: if the final thunk is applied, then the result of thunk-or is the result of that application, so scheme_tail_apply is used for the final application.