Artifact for “Binding as Sets of Scopes”

This artifact demonstrates the following claims from the paper:

  1. scope sets are an effective model for hygienic macros;

  2. the implementation with scope sets compares favorably to the previous implementation;

  3. performance of the new implementation is on par with the old implementation; and

  4. compatibility with existing Racket code is largely preserved.

The main part of the artifact is working version of Racket that uses scope sets for its macro expander. Since the Racket implementation is large, a miniature version of the macro-expander core is provided in the form of a PLT Redex model plus test cases. (More precisely, a sequence of models is provided, where each model corresponds to a subsection of the paper’s section 6.) The implementation provides a full-scale test, while the model is more reasonably human-checkable.

In addition to the macro system implementation and model, the artifact includes sources and results of building all packages from the Racket package registry.

For reference:

1 All-in-One Virtual Machine Image (Option 1)

The virtual machine image is intended as the distribution format of the artifact. The image contains a variant of this page, installed Racket versions, and an archive of packages and build results. In addition, we provide installers here for common platforms; you may find installing Racket on your machine natively to be easier for some purposes than running the virtual machine. For installers, see Installers and Models.

This virtual-machine image includes the Racket versions listed in Installers and Models. Each version is installed in a subdirectory of the racket user’s home directory.

The formal model (which runs in the newest version of Racket) is provided in the "model" subdirectory of the racket user’s home directory. See "README.txt" there for more information.

Source code for each Racket version is archive in the "src" subdirectory of the racket user’s home directory.

A copy of the packages archives and build results described in Packages and Build Results are in the "artifact" subdirectory of the racket user’s home directory. The "index.html" file there is a variant of this page.

2 Installers and Models (Option 2)

These installers are useful only if you don’t go the virtual machine route as described in All-in-One Virtual Machine Image.

As an alternative to the virtual machine:

While Racket releases are meant to allow multiple versions installed on a single machine, the version 6.2.900.17 and version 6.2.900.4 snapshot builds are configured in a potentially conflicting way. To avoid inteference between the versions, either install packages in only “installation scope” (as opposed to the default “user scope”) or configure the installations to have separate names by using

  raco pkg config --set name version-specific-name

and optionally, just to be sure,

  raco pkg config --set default-scope installation

Installations in the virtual machine of All-in-One Virtual Machine Image are configured this way.

3 Performance Tests

A basic test for the performance of the macro system is to bootstrap the racket language (which is built in many layers of macros on a kernel module) from source:

  time racket -c -l racket

That process should take 10-20 seconds on a modern machine.

A more extensive test is to run raco setup --clean followed by raco setup, which will rebuild all installed Racket libraries to bytecode from source. Rebuilding on a single-core machine takes on the order of an hour.

Finally, each successful package build starts and ends with a timestamp, and a comparison of timestamps shows similar installation times. However, macro expansion tends to be a small part of that time.

4 Macro Expander Source

The virtual machine image contains source in the "src" subdirectory of the racket user’s home directory.

The full Racket source code is available from the installer page for each version in Installers and Models. The main changes to the implementation are in "syntax.c", which implements the syntax-object data structure; the source file "compile.c" implements the macro expander, and it has fewer relevant changes. As a shortcut, we provide those sources for each version:

Inspecting the code in any details is unlikely to be fruitful for most readers, but perhaps some impressions can be drawn from a high-level skim. In the old "syntax.c", the monster function resolve_env is responsible for resolving a binding; the closest corresponding code in the new "syntax.c" is do_stx_lookup with do_stx_lookup_nonambigious.

These production implementations include many details on top of the core implementation strategies, so a comparison of models may be more tractable. The models for the set-of-scopes expander can be compared to models of the old expander, particularly since both models are written in a similar style.

5 Packages and Build Results

The virtual machine image contains a copy of the package archives and build results in the "artifact" subdirectory of the racket user’s home directory.

The following logs show the results of building and testing all registered packages with the old and new macro expanders at two points in time.

Use the catalog link above to replay any package installation into any Racket version. (For best results, install in installation scope to avoid entanglements between installations; the virtual-machine image is configured to avoid those problems.) For example, using in version 6.2.900.4 and the command (all on one line)
  bin/raco pkg install -i --catalog 3d-model
replays the 3d-model installation from the May package archive.

With substantial effort, the build results could be reconstructed using a script like "pkg-build.rkt", which uses the "pkg-build" package. Run the script in any recent version of Racket, adjusting the #:snapshot-url, #:pkg-catalogs, and #:installer-platform-name arguments as needed. A package-build run requires additional virtual machines to isolate each package’s build. The process takes an the order of a day for a given version and catalog.