Chapter 2.14 --- Extra Credit

Write a Tree-Shaker

"Whatever the answers are, here's one monkey that's going to keep on climbing, and looking around him to see what he can see, as long as the tree holds out."

Robert A. Heinlein, Methuselah's Children

You've probably noticed in previous exercises, that when creating executable binaries of your Lisp programs to distribute or share, their size on your file system has been somewhat larger than you expected---over 80 MBs even for just a simple command-line application. If you were to deploy this same Lisp application with a commercial implementation of ANSI Common Lisp, however, you would get a much smaller application: for a simple command-line application, probably less than 1 MB. What gives, right? That's a pretty big discrepancy!

As it turns out, whenever you dump a Common Lisp environment to an executable binary, you're dumping everything. The entire Lisp language, every contrib package, the REPL, the debugger, all the packages you've loaded in as dependencies, and your application itself. The commercial Lisps do this too---only they don't stop there, like the open-source implementations of Common Lisp---they then "shake the tree" of your Lisp application to prune all the unused symbols from the final executable. Your final executable binary then only contains a subset of Lisp needed to execute your program, and strips out everything else not needed for run-time.

There are pros and cons to both approaches. Many Lisp Hackers consider shipping the full Common Lisp environment with each instance of the application to be a feature---after all, you can embed a SWANK server into every app, and work with the live instance on the target platform, debugging and testing as it continues working. You can also provide a Lisp REPL to your users and let them customize everything in your program to their liking.

Commercial Lisps take a more traditional approach, and provide a clear separation between developers and users. So their binaries are stripped of everything that a user, in their view, should not have access to.

Whether or not you care about providing your users the full power of Common Lisp as a part of the application run-time, writing a tree-shaker is an interesting exercise, and may give you a deeper understanding of Lisp's implementation and execution on the machine level. To-date, the best example of a tree-shaker for SBCL was written several years ago by Juho Snellman, but as SBCL has gone under considerable development since that time, it requires a fresh perspective---which is a perfect opportunity for learning!

Revision Note: A More recent tree-shaker example is available from Burton Samograd, with some relevant chat history from IRC included.

Exercise 2.14.1

Shaking Trees vs. Stripping Binaries



Exercise 2.14.2

Pruning Trees



Exercise 2.14.3

Unneccessary Run-Time Packages



Exercise 2.14.4

Full Garbage Collection



Exercise 2.14.5

Disabling the Debugger



Exercise 2.14.6

Type Safety



Exercise 2.14.7

A Basic Tree-Shaker



Exercise 2.14.8

Code-Walking



Exercise 2.14.9

More Code-Walking



Exercise 2.14.10

Even More Code-Walking



Exercise 2.14.11

A Smart Tree-Shaker



Exercise 2.14.12

NUKE-LISP-AND-DIE

aka, Optimize, Collect, Shake, Save, Purify, Compress and Die



Exercise 2.14.13

Packaging the Tree-Shaker



Exercise 2.14.14

Revisiting the 2D Game Engine



results matching ""

    No results matching ""