logo raviqqe's logbook

Default library directories in Stak Scheme

Summary

What snow-chibi needs from an implementation

These facts come from the upstream source in lib/chibi/snow/.

Stak today (verified)

RequirementStatus
-A/-I flagsSupported by the interpreter and stak-compile
-A with a missing directoryWorks
.sld file with include relative to itWorks
Shebang scriptsWork
stak --versionPrints stak 0.12.28
Default library directoriesNone; the library-paths parameter starts empty
A way to print library directoriesNone from the command line; (library-paths) in (stak compile)
(exit 0)Exits with status 1 and prints Error: halt
cond-expand with (library (srfi 1))False, although (srfi 1) is built in
include-library-declarationsFails with procedure expected
-e flag to evaluate an expressionNone; the feature probe must go through a temporary file

The stak binary is defined by stak_sac::main! in sac/src/lib.rs, which parses arguments with clap before the Scheme program runs. -V, --version, -s, and --heap-size are consumed there, and every other argument reaches run.scm through the raw command line.

Other implementations

The paths below are from Homebrew installations probed locally, except for Meevax, which comes from its source.

ImplementationDefault directoriesEnvironment variableHow to query
Chibi 0.12.0$PREFIX/share/chibi, $PREFIX/lib/chibi, /usr/local/{share,lib}/snow, ./lib, .CHIBI_MODULE_PATH(current-module-path)
Gauche 0.9.15$PREFIX/share/gauche-0.98/site/lib, then the versioned system libraryGAUCHE_LOAD_PATHgauche-config --sitelibdir, *load-path*, gosh -V
Guile 3.0.11$PREFIX/share/guile/3.0, .../site/3.0, .../site, $PREFIX/share/guileGUILE_LOAD_PATH%load-path, (%site-dir)
Sagittarius$PREFIX/share/sagittarius/sitelib, then versioned directoriesSAGITTARIUS_LOADPATH(load-path)
Chicken 6.0.0$PREFIX/lib/chicken/12CHICKEN_REPOSITORY_PATH(repository-path), chicken-install -repository
Chez. onlyCHEZSCHEMELIBDIRS(library-directories)
Racket 9.3Per-user collects, then the installation’s collectsPLTCOLLECTS(current-library-collection-paths)
Gambit 4.9.8~~lib ($PREFIX/lib) and ~~userlib (~/.gambit_userlib)None(path-expand "~~userlib")
Meevax$XDG_DATA_HOME/meevax (else ~/.local/share/meevax), $PREFIX/share/meevaxNonemeevax --library-directories

The Chicken environment variable name is from memory. For other implementations snow-chibi supports, it queries (install-path #:libdir) on STklos, (scheme-library-paths) on Ypsilon, (scheme-paths) on TR7, (Cyc-installation-dir 'sld) on Cyclone, and (system-library-directory-pathname) on MIT Scheme.

Search order

Measured with an -I directory, an environment variable, and an -A directory all set:

Standards

Akku

Akku, the other Scheme package manager, installs into a project-local .akku/lib and generates an .akku/env script. That script exports each implementation’s own variable (CHIBI_MODULE_PATH, GAUCHE_LOAD_PATH, CHEZSCHEMELIBDIRS, GUILE_LOAD_PATH, SAGITTARIUS_LOADPATH, and others) and appends the shared R6RS_PATH and R7RS_PATH variables so that globally installed libraries remain reachable.

Conventions

Recommendation

  1. Search -I directories, then STAK_LIBRARY_PATH (colon-separated), then $XDG_DATA_HOME/stak (or ~/.local/share/stak), then a system directory such as /usr/local/share/stak, then -A directories. This matches Gauche and Guile.
  2. List the user directory before the system directory. Stak is installed with cargo install, so there is no installation prefix, and snow-chibi installs into the first directory it is given. A user directory first means installs without sudo, the same choice Meevax made.
  3. Add a command-line flag that prints the directories one per line, in search order. snow-chibi can then support Stak with the same few lines it uses for Meevax. The existing (library-paths) procedure in (stak compile) would return the same list.
  4. Put the defaults in the interpreter and REPL drivers (run.scm and repl.scm), not in the compiler frontend. stak-compile and stak-build then keep producing the same bytecode regardless of what is installed on the machine, and embedded and no_std builds are unaffected.
  5. Keep skipping directories that do not exist.

SRFI 176 is the standardized alternative to a custom flag, but it would replace clap’s -V handling in stak_sac::main!, which every binary built with that macro shares.

Decisions only the maintainer can make

Side findings

These are separate from the issue but block snow-chibi integration.

  1. exit treats only #t or no argument as success. (exit 0) and (exit 3) both print Error: halt and exit with status 1. snow-chibi’s SRFI probe ends with (exit 0), and its test runner fails any nonzero status. Chibi and Gauche pass integer arguments through as exit codes, and R7RS asks implementations to translate the argument into an appropriate exit value.
  2. cond-expand checks (library ...) requirements against a list fixed by define-features around line 334 of prelude.scm: (scheme base), (scheme read), (scheme write), (stak base), (stak continue), and (stak exception). (srfi 1), (scheme char), and every library on the load path test false, and (features) has no srfi-N entries. snow-chibi would conclude that Stak has no built-in SRFIs and install snow-fort’s (srfi 1), which Stak’s built-in library would then shadow because built-in libraries resolve before the load path.
  3. include-library-declarations inside define-library fails with procedure expected.

Sources