Kawa implements all the required and optional features of R5RS, with the following exceptions.
The entire "numeric tower" is implemented. However, some transcendental function only work on reals. Integral function do not necessarily work on inexact (floating-point) integers. (The whole idea of "inexact integer" in R5RS seems rather pointless ...)
Also, call-with-current-continuation
is only "upwards" (?).
I.e. once a continuation has been exited, it cannot be invoked.
These restricted continuations can be used to implement catch/throw
(such as the examples in R4RS), but not co-routines or backtracking.
Kawa now does general tail-call elimination, but only if
you use the flag --full-tail-calls
. (Currently, the
eval
function itself is not fully tail-recursive, in violation
of R5RS.) The --full-tail-calls
flag is not on by default,
partly because it is noticably slower (though I have not measured how
much), and partly I think it is more useful for Kawa to be compilatible
with standard Java calling conventions and tools.
Code compiled with --full-tail-calls
can call code
compiled without it and vice versa.
Even without --full-tail-calls
, if the
compiler can prove that the procedure being called is the current
function, then the tail call will be replaced by a jump.
This means the procedure must be defined using a letrec, not a
define (because the compiler does not know if someone might
re-define a global definition), and there must be no assignments
(using set!
) to the procedure binding.