Chapter 11 · 24 July – 17 September
Raku that travels
An interpreter that works in its developer's shell is the easy part. v4.0.0 was named, a month before any of its code existed, "Raku that travels". It set three goals: installing modules without Rakudo or zef, compiled binaries that carry everything they need or refuse to build, and Raku as a library other languages can call.
use XML, once parsed modules were cached--standalone turns any such skip into a build failure.Modules
zef installworks end to end under Raku++. The next day it installed a module from the live ecosystem, and every blocker it hit was a general engine bug.- A precompilation cache. It stores the parsed tree, not bytecode (there is none), and is validated by content hash, never by timestamp:
use XML16.0 → 5.7 ms interpreted. - NativeCall through libffi, loaded at run time. Before that the FFI was
dlsymand one over-wide prototype of eight integers and eight doubles. - A native extension ABI (
rakupp_ext.h). Its first user parsed a 278 KB JSON document in 2.7 ms, against about 440 ms for the same module's Raku code. The next day a check found that on Linux an extension's first call had always crashed: a plain ELF executable keeps its symbols out of the dynamic table. rakupp install, itself a Raku program. It resolves the fez index, verifies each file's checksum, runs the distribution's own tests, and writes the same store layout Rakudo and zef use. A seven-distribution graph installed by Raku++ loads under Rakudo, and both engines enumerate the same 727 SPDX licenses from it.uninstall --check's first real run found store damage that was breaking Rakudo's ownuse File::Temp.%?RESOURCESin compiled binaries. It had been an empty hash in every compiled binary.%?RESOURCES<x>answeredAny, and the program died with a message that never mentioned resources. Meanwhile--standalonereported "embedded 1 module" and exited 0.
The plan said to serve resources from memory. That was wrong: is native(%?RESOURCES<libraries/x>) hands its value to dlopen, which needs a path on a real filesystem. A distribution now writes its resources to one temporary directory on first use, and it is removed at exit. A binary that never reads a resource never creates one, and say "Hello" compiles byte-identically.
Raku as a library
The extension ABI turned out to be the harder half of an embedding API, so the two share one vocabulary of values rather than growing two. v3.1.0 (11 August) exported the C API, and the bindings followed: Python, C++, JavaScript on bun, Go and Rust on 12 August, then Wolfram on 24 August. Anton Antonov published the Wolfram one as a paclet, RakuppLink.
The reason anyone outside the project would care is grammars. "Embed Raku in Python" is abstract. "Use Raku grammars from Python" is something the host language has nothing like: a regex library gives you one pattern, not a composable grammar with named rules, inheritance and longest-token dispatch. The grammar stays a .raku file, and each host's class is generated from it. One corpus runs from every host in CI, and the outputs must match byte for byte.
More places to run
- OpenBSD, from an outside contribution: stack-size introspection and a CI job in a VM. Its archive has been a release asset since the next day.
- A grown-up command line. Perl's one-liner surface (
-n -p -a -F -l -0, in-place-i[.bak],-M, clusters like-lane), checked against a liveperl.-irefuses loudly where Perl is silent. Building it exposed thatmy $*OUT = $handledid not reroutesay. - Windows becomes a platform.
$*DISTRO.is-winhad been hard-codedFalse. The FFI went from eight integer arguments to sixteen, with pointers the width of a machine word: a realHMODULEhad reached its caller as-2003238912. There is a PowerShell one-liner and an installer that keepsPATHexpandable. curl -fsSL https://raku.online/install.sh | sh, which verifies SHA-256, andrakupp upgrade.- A report that the Linux build would not start on Ubuntu 22.04, Debian 12 or RHEL 9: it needed glibc 2.38. Builds moved to manylinux 2.28, and the floor is glibc 2.28, from 2018.