Details on the serialisation of closures and continuations
Closures are serialised by saving information about their lexical
environment at compile-time, and the values of the variables they
close over at runtime. More accurately, the fully macroexpanded
(another possible conflict with codewalked extensions) source
of a function that will reconstruct the complete lexical environment
of the closure, given the values of closed variables, and then
recreate the closure in that environment, is generated. That source is
compiled lazily, when needed, while the server is running. While this
should increase the speed at which programs are compiled, it can be
undesirable. (ensure-all-builders)
will compile, in advance, all the
deserialising functions.
Note that, in order to save space, lexical environments that are
identical modulo the equivalence of uninterned symbols are considered
equivalent. In any case, using uninterned symbols for equality
(as opposed to lexical variables or function) is a bad idea, since
their identity is not preserved by a print -> read
round-trip. While
using symbol-name
would make sense, using strings sounds like a better
idea.
Once the deserialising function has been generated, it is associated with an unique closure descriptor number and saved in a global hash table. The descriptor is used during serialisation instead of the source itself to save space and improve speed. A serialisable closure is thus defined by a closure descriptor number and a list of the values it closes over (in an arbitrary but important order).
Since both the descriptors (numbers) and the deserialising functions (or, rather, their source) can be printed readably, they can easily be serialised to migrate to another server or to improve load balancing and redundancy.
Finally, continuations are simply lists of (serialisable) closures,
generated at runtime by the bind
and dbind
macros, and are printed as
such. Since *print-circle*
is bound to T
during serialisation
(print
ing), sharing within a single continuation is
preserved. Object identity, however, is not, except for interned
symbols.
posted at: 00:00 | /Lisp/CommonCold | permalink