The State of Chez Scheme in Debian

Written by Gwen Weinholt on 2026-07-31

I have uploaded Chez Scheme 10.4.0 to Debian unstable. It has been a few years since there was a new Chez Scheme version in Debian, and that is all on me. ðŸ˜…

The new release builds fine on all architectures according to the build logs. In case you missed it, Chez Scheme got an infusion of energy from the Racket people and gained portable bytecode support a few years ago. So for those architectures where there is no native backend, Chez instead generates portable bytecode.

There was a problem with m68k and hppa where they would sometimes get the wrong endianness for the portable bytecode, possibly depending on which buildd picked them up. But that should be fixed now as debian/rules constructs the machine type from Debian’s build variables.

Debian Scheme Dream Team

I moved the package to the Debian Scheme Dream Team! So now there are more people who can help maintain it. The team has been gathering some mass recently, which is really nice to see. I hope that together we can make Scheme a stronger language in Debian.

Cross-compilation was broken

I enabled cross-compilation from amd64 to arm64 in the Salsa pipelines and found that it was actually broken! The problem was that cross-compilation kicks off a secondary build where several of our build parameters were missing. So the secondary build couldn’t find zuo and also got the wrong C compiler.

This has been fixed by patching build.zuo. This patch should be upstreamed.

Future work

The chezscheme-dev package is not something I have actually tested myself. It ships libkernel.a, main.o and scheme.h. Could be working, nobody has ever said otherwise. :)

Then there are the portable bytecodes! It would be possible to de-dupe those in the archive. They could be built as Architecture: all packages and be reused. Now, e.g., sparc64 and ppc64 both build threaded 64-bit big endian bytecode, so those exist at least twice in the archive.

Reproducible builds

Last, but not least, Chez Scheme builds are not reproducible. This is becoming a real problem now because Debian’s release team has made reproducible builds mandatory. Chez Scheme will not be part of future Debian releases unless this gets fixed.

Thankfully it does seem to be fixable. The root of the problem is that unique identifiers are used to support separate compilation. If anyone’s interested in the background then they can check out Oscar Waddell’s Ph.D. thesis (warning: .ps.gz file).

The implementation described in Section 3.5 supports both internal and top-level modules. For internal modules, the new names generated by the expander must be locally unique, i.e., not otherwise visible within the same top-level expression. For top-level modules within a single compilation unit, the names must be unique within the compilation unit. When multiple compilation units may be linked together, the names must be unique across compilation units.

– Oscar Waddell, Extending the Scope of Syntactic Abstraction, Â§3.6.1

Chez Scheme generates a UUID for each session that gets embedded into gensyms and that then gets embedded into the code. This satisfies the need for unique identifiers that are different between separate compilations. It ensures that things work smoothly when you are using the compiler yourself. But we want reproducible builds, meaning byte-for-byte identical builds, so the UUID is a problem.

When building packages for Linux distributions, things are a bit different than when you’re using the compiler yourself. Our build system can tell us what code went into the build, including the dependencies that brought in Scheme code, and if those stay the same then there is no need to use different identifiers compared to the previous time we built the same code.

I’m toying with the idea of generating a session key from the package version numbers and passing it to configure. I think it can be done without changing anything outside of the build system (the Zuo code). Conceptually we would be doing this:

(#%$set-top-level-value! '$session-key "k<hashed versions>-")
(compile-file "s/foo.ss")

It remains to be seen if this is enough or if there are other sources of non-determinism.