Features of the Hotdog Compiler

The Hotdog compiler features depend somewhat on the features of the target backend. Regardless of backend, however, Hotdog supports mostly R5RS Scheme. There is full support for the R5RS hygenic macros and most standard procedures. The current version, 0.1, does not support:

First-Class Continuations

There is no support for full continuations on any backends. Although future backends may support full continuations, the JVM and .NET backend will likely not. Regardless, all Hotdog compiler backends will support one-shot, upward continuations. Such exceptions function much like catch/throw exceptions, where control may be transferred non-locally (across function call boundaries), but only upward along the dynamic call stack.

Proper Tail Recursion

Full, proper tail recursion may not be supported on some backends. The JVM backend supports full tailcalls, if code is compiled will full-tailcall enabled. The C backend does not support full tailcalls, but it will be implemented soon. The .NET backend supports full tailcalls, with some limitiations imposed by the runtime. The compiler, however, transforms all simple tailcalls into loops, with both performance and space benefits. To give concrete examples, consider the following procedures:

(define (fact1 n r)
(if (< n 1)
r
(fact1 (- n 1) (* n r))))

(define (fact2 n)
(let loop ((n n) (r 1))
(if (< n 1)
r
(loop (- n 1) (* r n)))))

(define (fact-even n r)
(fact-odd (- n 1) (* r n)))
(define (fact-odd n r)
(if (= n 1)
r
(fact-even (- n 1) (* r n))))

As defined in R5RS Scheme, all of these procedures are properly tail recursive and hence require no stack space, even the fact-even and fact-odd procedures. In other words, full proper tail recursion requires that any call in tail position destroy the current stack frame before executing the call, regardless of the procedure called. Scheme requires support for tail calls to all procedures, regardless of whether the procedure is known or unknown at compile time.

The Hotdog compiler (like most LISP compilers) transforms simple tail recursions to self or non-escaping internal procedures into loops. For instance, the Hotdog compiler would transform the call to fact1 into a simple loop, and transform the fact2 internal loop procedure into a loop. However, the tail recursion in fact-even and fact-odd will not be recognized by the current Hotdog compiler, and hence may require stack space (depending on the backend).

Case-lambda

The Hotdog compiler natively supports a restricted version of the case-lambda syntax (see Scheme Request for Implementation 16). A natively compiled case-lambda has the following properties:

    1. Dispatch to a clause in the case-lambda is executed directly, regardless of the number of clauses in the lambda.

    2. No allocation occurs for fixed argument clauses of the case-lambda, when they are applicable, even if the case-lambda includes a vararg clause.

The syntax supported natively by the Hotdog compiler is any case-lambda clause meeting the following requirements:

    1. A clause with zero or more fixed arguments, and an optional vararg argument.

    2. Only one vararg clause may be present.

    3. Each fixed argument clause of the case-lambda satisfying 1) must differ by at least one argument.

For instance, the following case-lambda would be natively supported by the Hotdog compiler:

(define +
(case-lambda
(() 0)
((x) x)
((x y) (2+ x y))
((x y z) (2+ (2+ x y) z)
(rest (reduce 2+ 0 rest))))


The Hotdog compiler would accept the above definition of + and compile it into native code such that a call to (+ x y) would not allocate any objects on the heap, and would immediately dispatch to the (2+ x y) clause of the case-lambda for free.

Foreign Function Interface

A FFI for each target language is included for each backend. See the backend reference for more information.

Type Signatures and Type Checking

Near future versions of the Hotdog compiler will include support for procedural type signatures and static type checking.