6.16.6 Compiling Scheme Code

The eval procedure directly interprets the S-expression representation of Scheme. An alternate strategy for evaluation is to determine ahead of time what computations will be necessary to evaluate the expression, and then use that recipe to produce the desired results. This is known as compilation.

While it is possible to compile simple Scheme expressions such as (+ 2 2) or even "Hello world!", compilation is most interesting in the context of procedures. Compiling a lambda expression produces a compiled procedure, which is just like a normal procedure except typically much faster, because it can bypass the generic interpreter.

Functions from system modules in a Guile installation are normally compiled already, so they load and run quickly.

Note that well-written Scheme programs will not typically call the procedures in this section, for the same reason that it is often bad taste to use eval. By default, Guile automatically compiles any files it encounters that have not been compiled yet (see --auto-compile). The compiler can also be invoked explicitly from the shell as guild compile foo.scm.

(Why are calls to eval and compile usually in bad taste? Because they are limited, in that they can only really make sense for top-level expressions. Also, most needs for “compile-time” computation are fulfilled by macros and closures. Of course one good counterexample is the REPL itself, or any code that reads expressions from a port.)

Automatic compilation generally works transparently, without any need for user intervention. However Guile does not yet do proper dependency tracking, so that if file a.scm uses macros from b.scm, and b.scm changes, a.scm would not be automatically recompiled. To forcibly invalidate the auto-compilation cache, pass the --fresh-auto-compile option to Guile, or set the GUILE_AUTO_COMPILE environment variable to fresh (instead of to 0 or 1).

For more information on the compiler itself, see Compiling to the Virtual Machine. For information on the virtual machine, see A Virtual Machine for Guile.

The command-line interface to Guile’s compiler is the guild compile command:

Command: guild compile [option...] file...

Compile file, a source file, and store bytecode in the compilation cache or in the file specified by the -o option. The following options are available:

-L dir
--load-path=dir

Add dir to the front of the module load path.

-o ofile
--output=ofile

Write output bytecode to ofile. By convention, bytecode file names end in .go. When -o is omitted, the output file name is as for compile-file (see below).

-x extension

Recognize extension as a valid source file name extension.

For example, to compile R6RS code, you might want to pass -x .sls so that files ending in .sls can be found.

-W warning
--warn=warning

Enable specific warning passes; use -Whelp for a list of available options. The default is -W1, which enables a number of common warnings. Pass -W0 to disable all warnings.

-O opt
--optimize=opt

Enable or disable specific compiler optimizations; use -Ohelp for a list of available options. The default is -O2, which enables most optimizations. -O0 is recommended if compilation speed is more important than the speed of the compiled code. Pass -Ono-opt to disable a specific compiler pass. Any number of -O options can be passed to the compiler, with later ones taking precedence.

--r6rs
--r7rs

Compile in an environment whose default bindings, reader options, and load paths are adapted for specific Scheme standards. See R6RS Support, and See R7RS Support.

-f lang
--from=lang

Use lang as the source language of file. If this option is omitted, scheme is assumed.

-t lang
--to=lang

Use lang as the target language of file. If this option is omitted, rtl is assumed.

-T target
--target=target

Produce code for target instead of %host-type (see %host-type). Target must be a valid GNU triplet, such as armv5tel-unknown-linux-gnueabi (see Specifying Target Triplets in GNU Autoconf Manual).

Each file is assumed to be UTF-8-encoded, unless it contains a coding declaration as recognized by file-encoding (see Character Encoding of Source Files).

The compiler can also be invoked directly by Scheme code. These interfaces are in their own module:

(use-modules (system base compile))
Scheme Procedure: compile exp [#:env=#f] [#:from=(current-language)] [#:to=value] [#:opts=’()] [#:optimization-level=(default-optimization-level)] [#:warning-level=(default-warning-level)]

Compile the expression exp in the environment env. If exp is a procedure, the result will be a compiled procedure; otherwise compile is mostly equivalent to eval.

For a discussion of languages and compiler options, See Compiling to the Virtual Machine.

Scheme Procedure: compile-file file [#:output-file=#f] [#:from=(current-language)] [#:to=’rtl] [#:env=(default-environment from)] [#:opts=’()] [#:optimization-level=(default-optimization-level)] [#:warning-level=(default-warning-level)] [#:canonicalization=’relative]

Compile the file named file.

Output will be written to a output-file. If you do not supply an output file name, output is written to a file in the cache directory, as computed by (compiled-file-name file).

from and to specify the source and target languages. See Compiling to the Virtual Machine, for more information on these options, and on env and opts.

As with guild compile, file is assumed to be UTF-8-encoded unless it contains a coding declaration.

Scheme Parameter: default-optimization-level

The default optimization level, as an integer from 0 to 9. The default is 2.

Scheme Parameter: default-warning-level

The default warning level, as an integer from 0 to 9. The default is 1.

See Parameters, for more on how to set parameters.

Scheme Procedure: compiled-file-name file

Compute a cached location for a compiled version of a Scheme file named file.

This file will usually be below the $HOME/.cache/guile/ccache directory, depending on the value of the XDG_CACHE_HOME environment variable. The intention is that compiled-file-name provides a fallback location for caching auto-compiled files. If you want to place a compile file in the %load-compiled-path, you should pass the output-file option to compile-file, explicitly.

Scheme Variable: %auto-compilation-options

This variable contains the options passed to the compile-file procedure when auto-compiling source files. By default, it enables useful compilation warnings. It can be customized from ~/.guile.