In Larceny, file names generally follow Unix conventions, even on Windows. The following suffixes have special meanings to some components of Larceny.
.sld
define-library
syntax.
.sls
library
syntax.
.sps
import
declaration
followed by definitions and expressions).
.scm
import
declarations and don't define any R7RS/R6RS libraries.
.sch
.scm
used by Larceny developers.
.slfasl
.sld
, .sls
, or .sps
file.
.fasl
.scm
or .sch
).
.mal
.lap
.lop
.heap
larceny.bin
runtime).
In Larceny, R7RS define-library
and R6RS library
syntaxes
are mostly interchangeable. The R6RS for
and meta
keywords
may be needed when defining syntax-case
macros, but the R7RS
syntax is otherwise more versatile because of its include
and
cond-expand
features. For new code, we recommend the R7RS
define-library
syntax.
Although the R7RS define-library
syntax allows export
and
import
declarations to be placed anywhere at the top level of
the syntax, it is standard practice to use only one export
declaration per library, placed immediately following the name
of the library, and to use only one import
declaration per
library, placed immediately following the export
declaration.
Some of Larceny's compilation tools rely upon the convention described within the note above, and may not work if that convention is not followed.
An R7RS library definition may be split into two or more files,
with the primary .sld
file containing one or more include
declarations that include .scm
files. If foo.sld
is the
primary file, then the included file is ordinarily named
foo.body.scm
and placed within the same directory as foo.sld
.
If more than one .scm
file is included, we recommend
foo.body1.scm
, foo.body2.scm
, and so on. A Larceny-specific
version of foo.body2.scm
that's conditionally included using
the cond-expand
feature might be named foo.body2.larceny.scm
.
Portable source code can be tailored to Larceny and other
implementations of the R7RS by combining implementation-specific
mechanisms such as Larceny's -path
option with the include
and cond-expand
features of R7RS libraries.
Larceny's root directory should contain the following files:
larceny scheme-script larceny.bin larceny.heap startup.sch
The following subdirectories are also essential for correct operation of some features of some modes in some varieties of Larceny:
include lib lib/Base lib/Debugger lib/Ffi lib/MzScheme lib/R6RS lib/SRFI lib/Standard lib/TeachPacks
The include
subdirectory is used when compiling files with
Petit Larceny.
The startup.sch
file tells Larceny's require
procedure to
search some of the lib
subdirectories for libraries that are
loaded dynamically.
The R7RS and R6RS standards do not specify any mapping from library names to files or other locations at which the code for a library might be found.
R6RS non-normative appendix E emphasizes the arbitrariness of such mappings:
Implementations may take radically different approaches to storing source code for libraries, among them: files in the file system where each file contains an arbitrary number of library forms, files in the file system where each file contains exactly one library form, records in a database, and data structures in memory. Similarly, programs and scripts may be stored in a variety of formats. Platform constraints may restrict the choices available to an implementation, which is why the report neither mandates nor recommends a specific method for storage. Implementations may provide a means for importing libraries…. Similarly, implementations may provide a means for executing a program represented as a UTF-8 text file containing its source code…. | ||
-- |
To put it more starkly:
Although implementations of the R6RS may "provide a means for importing libraries" or "executing a program", they don't have to.
R7RS section 5.1 urges implementations to be reasonable:
Implementations which store libraries in files should document the mapping from the name of a library to its location in the file system. | ||
-- |
Fortunately, de facto standards have been emerging. Larceny supports those de facto standards by providing these Larceny-specific mechanisms:
(larceny compiler)
,
may be placed in one of the directories searched
by Larceny's
autoload feature, provided
those libraries are located in files that follow Larceny's
standard naming conventions as described in
the next section.
-path
option
to specify directories that contain other libraries
the program may import, provided those libraries are
located in files that follow Larceny's standard naming
conventions as described in
the next section.
LARCENY_LIBPATH
environment variable
to specify directories that contain other libraries
the program may import, provided those libraries are
located in files that follow Larceny's standard naming
conventions as described in
the next section.
R7RS programs may use any of those five mechanisms, and may also use a sixth mechanism: An R7RS program can be written as a little configuration program that loads the program's libraries from files before any libraries are imported. This sixth mechanism appears to be portable, but is not available to R6RS programs executing in Larceny's R6RS mode because it mixes execution with macro expansion, which is explicitly forbidden by one of the R6RS standard's "absolute requirements".
Suppose Larceny's -path
option is used to specify
a certain directory, and the program imports a
nonstandard library whose name is of the form
(name1 name2 … lastname)
.
Larceny will search for that library in the following
files:
directory/name1/name2/…/lastname.larceny.slfasl
directory/name1/name2/…/lastname.larceny.sld
directory/name1/name2/…/lastname.larceny.sls
directory/name1/name2/…/lastname.slfasl
directory/name1/name2/…/lastname.sld
directory/name1/name2/…/lastname.sls
directory/name1/name2.larceny.slfasl
directory/name1/name2.larceny.sld
directory/name1/name2.larceny.sls
directory/name1/name2.slfasl
directory/name1/name2.sld
directory/name1/name2.sls
directory/name1.larceny.slfasl
directory/name1.larceny.sld
directory/name1.larceny.sls
directory/name1.slfasl
directory/name1.sld
directory/name1.sls
The search starts with the first of those file names, continues with the following file names in order, and ends when a file with one of those names is found. The imported library must be one of the libraries defined within the first file found by this search, since the search is not continued after that first file is found (except as noted in the next paragraph).
If the search ends by finding a file whose name ends
with .slfasl
, then Larceny checks to see whether
there is a file in the same directory with the same
root name but ending with .sld
or .sls
instead of .slfasl
.
If the .sld
or .sls
file has been modified since the .slfasl
file was last modified, then a warning is printed and
the .sld
or .sls
file is loaded instead of the .slfasl
file.
Otherwise the .slfasl
file is loaded.
The R6RS allows arbitrary mappings from library names to library
code. Larceny takes advantage of this by ignoring version
numbers when mapping library names to files, and by (virtually)
rewriting any version number that may be specified in the
definition of a library so it matches any version specification
that appears within the import
form. Furthermore Larceny
allows different versions of the same library to be imported,
but Larceny's algorithm for resolving library references
ensures that the different versions of a library will be
identical except for their version numbers, which have no
meaningful semantics. Although Larceny's treatment of versions
conforms to the R6RS specification, it should be clear that
version numbers serve no purpose in Larceny. Since the R6RS
version feature has no usefully portable semantics and has
been ignored by most implementations of the R6RS, it is
deprecated.
In R5RS mode, Larceny's -path
option
and LARCENY_LIBPATH
environment variable
may be used to
specify directories to be searched by the require
procedure, which takes a single symbol libname as
its argument.
The require
procedure will search for the following
files in every directory that is part of the current
require path, starting with the directories specified
by LARCENY_LIBPATH and the -path
option:
libname.fasl
libname.sch
libname.scm
These files are expected to contain R5RS code, not library definitions. Otherwise the search proceeds much the same as when searching for an R7RS/R6RS library.
The require
path is specified by startup.sch
in Larceny's
root directory, but may be changed dynamically using the
current-require-path
parameter. Changing the require
path
is not recommended, however, because Larceny relies on the
require
path for dynamic loading of libraries used by several
important features of Larceny, notably R7RS and R6RS modes.
libname must be a symbol that names an R5RS-compatible library within the current require path.
If the library has not already been loaded, then it is
located and loaded. If the library is found and loaded
successfully, then require
returns true; otherwise an
error is signalled.
If the library has already been loaded, then require
returns false without loading the library a second time.
Procedure current-require-path
(current-require-path ) => stringlist
(current-require-path stringlist)
The optional argument is a list of directory names
(without slashes at the end) that should be searched
by require
and (in R7RS/R6RS modes)
by Larceny's autoload
feature.
Returns the list of directory names that will be
searched.