I did a small proof-of-concept tree shaker for SBCL. It doesn't do much, and it's not very good at what little it does. In the following transcript we create a scandalously small core that actually does something useful (gzip compression with Salza).
% /opt/packages/sbcl/0912gc1/bin/sbcl --noinform --userinit /dev/null * (load "gziplisp") T * (load "shakelisp") T * (shake-lisp-and-die "gzipcore" #'gzip::main) [doing purification: roots handlers stack bindings static cleanup done] [undoing binding stack and other enclosing state done] [saving current Lisp image into /tmp/gzipcore: writing 7255536 bytes from the read-only space at 0x01000000 writing 4643256 bytes from the static space at 0x05000000 writing 4096 bytes from the dynamic space at 0x09000000 done] % ls -l gzipgz gziplisp gzipcore ls: gzipgz: No such file or directory -rw-r--r-- 1 jusnel 11911168 Jul 6 06:02 gzipcore -rw-r--r-- 1 jusnel 3195 Jul 6 05:45 gziplisp % /opt/packages/sbcl/0912gc1/bin/sbcl --core gzipcore --noinform gziplisp % ls -l gzipgz -rw-r--r-- 1 jusnel 1276 Jul 6 06:03 gzipgz
/bin/gzip is a bit under 60kB, so we only lose by a factor of 200!