Larceny provides libraries for loading and compiling ERR5RS/R6RS libraries and for timing benchmarks. Future versions of Larceny will offer more ERR5RS/R6RS libraries.
The (larceny load)
library exports both the
load
procedure of (err5rs load)
and r5rs:require
, which is a renaming of
the require
procedure used by
Larceny's R5RS mode.
In Larceny's ERR5RS mode,
the load
procedure can load
R5RS libraries and programs as well as ERR5RS/R6RS
libraries.
The r5rs:require
procedure should be used only for dynamic loading of
R5RS libraries into Larceny's underlying R5RS system. The
variables defined by that library can be imported into
an ERR5RS session or ERR5RS/R6RS library or program using a
primitives
clause in an import
form.
These procedures should be used only at an interactive top
level and in files that will be loaded into an interactive top
level. Calls to these procedures have no effect at compile
time, and should not appear in files that will be compiled
separately; use the library
and import
syntaxes instead.
The (larceny compiler)
library exports the
load
and r5rs:require
procedures of (larceny load)
,
the
current-require-path
procedure, the
compile-file
,
compile-library
, and
compile-stale-libraries
procedures described below,
and the
compiler-switches
procedure.
These procedures can be used to compile ERR5RS/R6RS libraries and top-level programs before they are imported or executed. This is especially important for Petit Larceny, which would otherwise use an interpreter. For native Larceny, whose just-in-time compiler generates native machine code as source libraries and programs are loaded, imported, or executed, the main advantage of separate compilation is that compiled libraries and programs will load much faster than source libraries and programs.
The main disadvantage of separate compilation is that
compiled libraries and programs go stale when their
source code is changed or when a library on which they
depend is changed or recompiled. Stale libraries and
programs can be dangerously inconsistent with libraries
on which they depend, so Larceny checks for staleness
and refuses to execute a stale library or program.
The compile-stale-libraries
procedure provides a convenient way to recompile stale
libraries and programs.
(compile-file sourcefile [slfaslfile])
Compiles sourcefile, which must be a string naming
a file that contains source code for one or more
ERR5RS/R6RS libraries or a top-level program.
If slfaslfile is supplied as a second argument,
then it must be a string naming the file that will
contain the compiled code; otherwise the name of
the compiled file is obtained from sourcefile
by replacing the ".sls
" suffix with ".slfasl
".
(compile-library sourcefile [slfaslfile])
Compiles sourcefile, which must be a string naming
a file that contains source code for one or more
ERR5RS/R6RS libraries.
Apart from its unwillingness to compile top-level
programs, compile-library
behaves the same as
compile-file
above.
Procedure compile-stale-libraries
(compile-stale-libraries changedfile)
If no argument is supplied, then all ".sls
" files that
lie within the current directory or a subdirectory are
recompiled.
If changedfile is supplied, then it must be a string giving the absolute pathname of a file. (In typical usage, changedfile is a source file that has been modified, making it necessary to recompile all files that depend upon it.) Compiles all ERR5RS/R6RS library files that lie within the same directory as changedfile or a subdirectory, and have not yet been compiled or whose compiled files are older than changedfile.
In future versions of Larceny, compile-stale-libraries
might compile only the source files that depend upon
changedfile.
(compiler-switches mode)
If no argument is supplied, then the current settings
of all compiler switches are displayed. Each of those
switches is itself a parameter that is exported by the
(larceny compiler)
library. Calling any individual
compiler switch with no arguments will return its current
setting. Calling any individual compiler switch with an
argument (usually a boolean) will change its setting to
that argument.
The compiler-switches
procedure may also be called with
one of the following symbols as its argument:
default
sets most compiler switches to their default settings.
fast-safe
enables all optimizations but continues to generate
code to perform all run-time type and range checks that
are needed for safety
(in the traditional sense, not the R6RS sense).
fast-unsafe
enables all optimizations and also disables type and
range checking. This setting is deprecated because it
compromises safety (in the traditional sense).
slow
turns off all optimizations.
standard
sets compiler switches for maximal conformance to the
R5RS and R6RS standards.
The standard
setting is deprecated because it generates
very slow code (because the R5RS makes it difficult to
inline standard procedures), disables most compile-time
checking (because the R6RS forbids rejection of programs
with obvious errors unless the R6RS classifies the errors
as syntactic), and may also compromise the portability or
interoperability of ERR5RS/R6RS libraries and programs
(because the R6RS outlaws several extensions that Larceny
uses to improve its compatibility with other implementations
of the R5RS and R6RS as well as interoperability between
Larceny's own R5RS and ERR5RS/R6RS modes).
Selective toggling of compiler switches is almost always
better than using the standard
setting.
To improve R5RS conformance without sacrificing too much
performance, set the benchmark-mode
switch to false and
set the integrate-procedures
switch to false only when
compiling files that need to be sensitive to redefinitions
of standard procedures.
For R6RS libraries and programs, setting the benchmark-mode
and global-optimization
switches to false will eliminate a
couple of minor conformance issues with only a small loss
of performance and without sacrificing compile-time checking
or portability.
The (larceny benchmarking)
library exports the
time
syntax and run-benchmark
procedure described
below.
Syntax time
(time expression)
Evaluates expression and returns its result after printing approximations to the storage allocated and time taken during evaluation of expression.
> (time (fib 30)) Words allocated: 0 Words reclaimed: 0 Elapsed time...: 49 ms (User: 48 ms; System: 0 ms) Elapsed GC time: 0 ms (CPU: 0 in 0 collections.) 832040
(run-benchmark name iterations thunk predicate)
Given the name of a benchmark, the number of iterations to be performed, a zero-argument procedure thunk that runs the benchmark, and a unary predicate that checks the result of thunk, prints approximations to the storage allocated and time taken by iterations calls to thunk.
> (run-benchmark "fib30" 100 (lambda () (fib 30)) (lambda (x) (= x 832040))) -------------------------------------------------------- fib30 Words allocated: 0 Words reclaimed: 0 Elapsed time...: 4828 ms (User: 4824 ms; System: 4 ms) Elapsed GC time: 0 ms (CPU: 0 in 0 collections.)
The (larceny records printer)
library exports the
two procedures described below. These procedures
can be used to override Larceny's usual printing
of records and opaque types that were defined using
the records libraries.
(rtd-printer rtd) => maybe-procedure
Given a record type descriptor, returns its custom print procedure, or returns false if the rtd has no custom print procedure.
(rtd-printer-set! rtd printer)
Given a record type descriptor rtd and a printer for instances of that rtd, installs printer as a custom print procedure for rtd. The printer should be a procedure that, given an instance of the rtd and a textual output port, writes a representation of the instance to the port.