r7rs Libraries and Basic Extensions
Like with the other r7rs issues, this is specified in r7rs.pdf.
This is primarily described in §5.6's description of define-library
, with the addition of library-importing import
declarations from §5.2.
This portion of the Scheme language is very different from CL. In Common Lisp, there is a package system via defpackage
, but packages are just namespaces for symbols. In typical usage, the package is defined at the top of a file or in a separate package.lisp
and then the file(s) using that package have an in-package
specifying the package that they are using. On the other hand, in good CL style, the equivalent of import
must take place within a defpackage
.
Here, include
is based on including filenames, essentially inverting how the CL defpackage
works. The Scheme library specifies which files are internal rather than the files specifying which libraries they are in. This system also explicitly involves filenames, unlike CL's package system, which means that the library feature somewhat overlaps with asdf:defsystem
's system feature.
This winds up being almost like ASDF's package-inferred-system, combining a CL package and a CL system, but without the one-package-per-file (or in this case one-library-per-file) style of package-inferred-system. Instead, it's more idiomatic in r7rs for define-library
to be in a separate .sld
file, which is somewhat similar to a CL convention of using one package.lisp
per directory. This define-library
file loading needs to be extended to include CL files, not just Scheme files. This is called include-lisp
in the draft of the standard library definitions.
Procedures, macros, etc., defined in Common Lisp need to be provided in libraries defined in Common Lisp via define-scheme-library
. These can be imported in define-library
in Scheme as if they were defined in Scheme's define-library
. The standard-procedures
defined this way are currently provided via (airship r7rs)
and they are imported by the core Scheme libraries.
Initially, just turning this into slash-separated package names is probably the way to go (e.g. the library (scheme base)
is also the CL package airship-scheme/scheme/base
), but eventually ASDF system integration would be a good idea so every Scheme library would be both a CL package and an ASDF system. ASDF integration will belong in another, full issue.
In short, things will be based on the CL package system. The Scheme environment will be wrapped in a let
closure since it is a Lisp-1 (no need for flet
here). Importing another library will rebind things locally ("renaming" will be trivial). This would lead to the result where a set!
on a global form from another library (often not permitted altogether in Schemes) would only affect the library-local binding, not the original binding. It also introduces a limited degree of hygiene in unhygienic macros (similar to CL) since a macro defined in another library will be referring to a different symbol namespace, making it harder to accidentally redefine something that the macro is using.