
Ask HN: How does Common Lisp implement hot-reloading? - register
I have always wondered how Common Lisp implements hot-reloading on live functions in multithreaded contexts.<p>A typical approach used in other languages or debuggers is either to use a dispatch table or to have some NOP bytes at the beginning of every function that could be rewritten into a jmp to the new function definition. In the first case the code incurs a performance penalty for every invocation. In the latter there is no performance hit however the call stack must be kept completely unchanged. This doesn&#x27;t seem to match the experience one achieves with SBCL on Linux where calls don&#x27;t seem to be slowed down and one can recompile just some forms in the middle of the stack. It seems that in some way the CL compiler could update also the call stack. The only other language that reaches the same level of interactivity is Smalltalk for which however I know only about of single-threaded implementations. How is CL different from other languages with respect to this? Where can I find more technical details about how hot-reloading is implemented in CL?<p>Cheers
======
kazinator
A function is an object. When we redefine a global function, we're simply
replacing the symbol's function binding to point to a new function object.
That can be an atomic operation: a word-sized cell is overwritten.

If one or more threads are executing the old function, then they continue to
do that. That object is referenced by those threads and so doesn't become
garbage until the last thread stops executing it. Newly issued calls to that
function go to the new one through the newly established binding.

ANSI CL allows functions that are in the source file (actually compilation
unit) to use more efficient calling; they don't have to go through the global
symbol function binding. The idea is that compilation units are replaced at
once, rather than individual functions. Call optimizing behavior can be
overridden for individual functions by _declaim_ -ing them _notinline_.

~~~
register
Ok so this means that calls accross compilation units always incur an
indirection, right? Also I don't get how swapping the whole compilation unit
can be achieved atomically. A compilation unit might be composed by several
functions. Where can I find more? I have tried to look in the literature but
haven't found anything that reaches this level of detail.

~~~
segmondy
do you understand lisp symbols? read up on it and try to understand how they
are represented internally, that's the key.

------
bjourne
A very similar question was asked a few weeks ago in another Ask HN. See my
answer there
[https://news.ycombinator.com/item?id=18111600](https://news.ycombinator.com/item?id=18111600)

