How to replace a running function in Common Lisp?

2020-07-11 04:19发布

Suppose we use SBCL's #'save-lisp-and-die to create an server applicatioon App1, which works very well. Now we want to replace a function #'func1 with a new version without stopping App1. How can we do it in Common Lisp ?

Any suggestion is appreciated !

2条回答
混吃等死
2楼-- · 2020-07-11 04:57

I personally ensure that SWANK (the server part of SLIME) is running, so that I can connect to the image at any time with Emacs+SLIME and redefine whatever I want.

(ql:quickload "swank")
(swank:start-server :port 1234) ;; listen for SLIME connections on port 1234

Then in Emacs, you can M-x slime-connect, and follow the prompts.

If you don’t want to do this for whatever reason, your implementation might offer something specific.

查看更多
爷、活的狠高调
3楼-- · 2020-07-11 05:01

You need to load the new function definition. Then new function will be available immediately; code will call newly loaded function.

New function definition may be loaded in many ways:

  • (load (compile-file "file.lisp")) where file.lisp is a source code for function
  • (load "file.fasl") where file.fasl is compiled source code
  • (eval (defun ...))

Of course, there are exceptions and complications:

  • This will not replace already running calls of previous functions; for example, an infinite event loop can not be changed this way - it will have to support some kind of stopping and calling a new function. However, such long-running functions are rare. It can be worked around by using recursion instead of looping (but not all compilers do tail-call optimization).
  • If you somewhere grabbed a pointer to function (for example, by (function FOO) where FOO is the name of a function), it will retain its old value. To avoid this, use symbols instead of function pointers (symbols are funcallable).
  • The code of a function is a subject to garbage collection. You should be careful not to leave references to old versions of a function lying around. Also, if some functions become not needed, you should not forget to fmakunbound their symbols.
  • If the function was used at compile time, all of the affected code should also be reloaded
  • If you had high levels of optimization (which is not by default), compiler might have inlined the function into others. CLHS discriminates the cases when redefining a function becomes «undefined behavior».

But in practice, code reloading works well in most Common Lisp implementations.

查看更多
登录 后发表回答