Skip to content

RationalizingLarceny

Will Clinger edited this page May 26, 2016 · 2 revisions

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.)

Installation

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:

  1. an environment variable ($LARCENY_ROOT, %LARCENY_ROOT%)
  2. a path hard-coded in a batch file or shell script
  3. 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 with Larceny

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.

Testing

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)"
  • 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 in test/Lib

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.

Host support

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.

Libraries

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.

Building the Larceny system

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.

Clone this wiki locally