-
Notifications
You must be signed in to change notification settings - Fork 32
RationalizingLarceny
This document proposes ideas to make the Larceny system more consistent and easier to use. (This page was updated for v0.93, and has been partially updated for v0.99.)
Larceny binary distributions should work wherever they are unpacked.
On Linux, it is now possible for /usr/local/bin/larceny
(or whatever)
to be a symbolic link to the larceny
script found within some binary
distribution of Larceny. That doesn't work on other machines.
On MacOS X, Will creates a symbolic link from /usr/local/lib/Larceny
to the directory holding a binary distribution, copies the larceny
script to /usr/local/bin
, and edits that script so
LARCENY_ROOT=/usr/local/lib/Larceny
. Updating to a new version then
becomes a matter of downloading its binary distribution, unpacking it,
and changing the symbolic link.
With that kind of help, Larceny executables can determine their location on disk and find other files as necessary from there. Two global parameters are involved:
-
current-larceny-root
: String -
current-require-path
: List(String)
current-larceny-root should be the root directory of the larceny distribution, used to location default heap images and include files. current-require-path should be a search path for the larceny library (more below).
We determine larceny-root in a number of ways, in this order:
- an environment variable (
$LARCENY_ROOT
,%LARCENY_ROOT%
) - a path hard-coded in a batch file or shell script
- the path to the executable (in which case a warning is issued)
The parameter is modifiable from within the system; however,
command-line arguments or environment variables should supersede
anything set in ~/.larceny
, and currently don't.
current-require-path
is initially be derived from current-larceny-root
,
and may be extended by ~/.larceny
.
(Speaking of which: the .larceny
misfeature should be removed
or documented. Will thought it had been removed, but it's still
there.)
Larceny should be able to override the system path when looking for
external tools such as cc
and nasm
.
Compiling should be as similar as possible across the Larceny flavors.
(We may have taken that too far. Compiling R5RS code is necessarily different from compiling R7RS/R6RS code, because the compiler has to assume the free identifiers of R5RS code refer to names in the R5RS global environment, whereas it would be an error for R7RS/R6RS to have any free identifiers that aren't imported (and that's checked at compile time). As a consequence of that difference, compiled R5RS code is loaded into Larceny's underlying R5RS environment, even in R7RS modes, which confuses users who expect loading compiled code to behave the same as loading source code. Maybe users should get a warning when they load compiled R5RS code into an R7RS session.)
Felix's proposal below assumes everything is R5RS, which is no longer true.
I propose the following interface:
; compile foo.sch, output to foo.fasl and foo.{dll,exe,so}:
(compile-file "foo.sch")
; compile foo.sch, output to bar.fasl and bar.{dll,exe,so}:
(compile-file "foo.sch" "bar.fasl") ; output to bar.fasl ...
; compile {foo,bar,baz}.sch, output to qux.fasl and qux.{dll,exe.so}
(compile-file '("foo.sch" "bar.sch" "baz.sch") "qux.fasl")
In the one source form, the destination is optional. In the multiple
source form, the destination is required. If we
(define compile-files compile-file)
, this has the advantage that it subsumes both systems
without being ambiguous. (We probably should unify it with Common
Larceny's build-application
as well.)
It would be great if we could find a way to combine fasl
and so
/dll
into
one file. On Windows, this actually presents a serious difficulty, since
the current split makes it possible to compile a file while it's also
loaded.
I'd also be interested in investigating moving the Intel assembler into Petit Larceny and generally making it work more like SPARC Native Larceny. IASN Larceny is this.
The tests are somewhat fragmented, and some are out of date.
The nightly builds run most of the tests in the following directories, but only some of the test results are reported on the nightly builds web page:
test/Lib
-
test/Compiler
(basic sanity tests only) test/Benchmarking/CrossPlatform
- Racket's R6RS tests (not part of Larceny's source)
test/R7RS/Lib
The following files and directories contain tests that ought to be added to the nightly testing:
test/R7RS/Numbers/clisp-number-tests.sps
test/R7RS/conflicts.scm
test/R7RS/srfi.scm
- `lib/SRFI/test
We might consider replacing the R5RS cross-platform benchmarks with
- `test/Benchmarking/R7RS
That leaves the following directories:
-
test/Jaffer/r4rstest.scm
- to be run with
larceny --r5rs --foldcase -- -e "(integrate-procedures #f)"
- to be run with
-
test/Boot
- used only for early development of new systems
-
test/FFI
- Larceny's FFI needs TLC
-
test/GC
- should test all garbage collectors
-
test/Stress
- looks pretty similar to the cross-platform benchmarks
-
test/Sparc
- will be subsumed by
run-exception-tests
intest/Lib
- will be subsumed by
These tests use many different protocols to report their results, which makes them hard to summarize for the nightly builds web page. A few tests are commented out, and it's not always clear why. Some tests don't pass, and it's not always clear if they are supposed to.
At this point, we are mainly concerned with testing for R7RS compliance. The R4RS/R5RS/R6RS tests serve primarily as regression tests, to let us know if we break something.
The test reporting in test/Lib
and the R6RS/R7RS tests is not bad,
and it would be nice if more of our tests reported those results in
similar syntax, but many of our tests were written by other people
whose preferences differ from ours.
A user, upon building from the source distribution, should be able to run all appropriate tests easily from the build environment.
Once upon a time, we were able to build Larceny using MzScheme 209 and 3xx, and perhaps Chez Scheme. MzScheme has evolved into Racket, which is no longer standard or stable enough for us to use. Sagittarius looks like it's the best of the other R7RS/R6RS implementations.
We have adopted a require
feature for R5RS code, and R7RS/R6RS libraries
rely on the require
infrastructure for auto-loading of libraries. This
has worked pretty well.
We're having some trouble with libraries that use the FFI. We've worked around this by implementing a couple of things as syscalls so we don't have to go through the FFI, and we're avoiding some of the other problems by not compiling libraries that use the FFI. It would be better if we could ship compiled forms of libraries that use the FFI, but that's hard because ABIs are inherently less stable than APIs.
It would be nice if this were as similar as possible for native, Petit, and Common Larceny.
Common Larceny is still an outlier, but we haven't been releasing any new versions of it.