How to replace an executable function in Common Lisp?

Suppose we use SBCL # 'save-lisp-and-die to create an App1 application that works very well. Now we want to replace the # # func1 function with a new version without stopping App1. How can we do this in Common Lisp?

Any suggestion appreciated!

+4
source share
2 answers

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

The definition of a new function can be loaded in various ways:

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

Of course, there are exceptions and complications:

  • This will not replace already running calls to previous functions; for example, an infinite loop of an event cannot be changed this way - it will have to support some stopping and calling a new function. However, such long-lasting functions are rare. It can be circumvented using recursion instead of a loop (but not all compilers do tail-call optimization).
  • If you grab a pointer to a function somewhere (for example, (function FOO) , where FOO is the name of the function), it will retain its old value. To avoid this, use characters instead of function pointers ( funcall characters funcall capable).
  • The function code is a garbage collection object. You must be careful not to leave links to old versions of the function lying around. In addition, if some functions are not needed, you should not forget their symbols fmakunbound .
  • If the function was used at compile time, all affected code must also be reloaded
  • If you had high optimization levels (which is not the default), the compiler could include the function in others. CLHS distinguishes between cases when overriding a function becomes an “undefined behavior”.

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

+3
source

I personally guarantee that SWANK (the server side of SLIME) is running, so I can connect to the image at any time using 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 Mx slime-connect and follow the prompts.

If you do not want to do this for any reason, your implementation may offer something specific.

+10
source

Source: https://habr.com/ru/post/1391175/


All Articles