Lets say I have a REPL to a process running my Common Lisp code. It could be running SWANK/SLIME.
I want to update a function defined with defun in my live process. The function may have captured some variables in a let binding. Essentially, this function is a closure.
How can I update the code in that closure without losing the data that it has captured?
2019-11-03: I selected one answer below, but I recommend reading all of the answers. Each has an interesting insight.
Basically you can't and that's one of the reasons to avoid using DEFUNs in LETs.
One could create a new closure and try to copy the state from the old one into the new one.
One problem is that portable Common Lisp does not allow much dynamic access to closures. One can't 'go' into a closure and add something or replace something from the outside. There are no reflective or introspective operations defined for closures.
Thus everything you later want to do with a closure needs to be already present in the closure generating code.
Let's say you have this code:
(let ((foo 1))
(defun add (n)
n))
Now we decide that add
is wrong and should actually add something?
We want the effect of this:
(let ((foo 1))
(defun add (n)
(+ n foo)))
How can we modify the original? We basically can't.
If we had:
(let ((foo 1))
(defun get-foo ()
foo)
(defun add (n)
n))
We could do:
(let ((ff (symbol-function 'get-foo))
(fa (symbol-function 'add)))
(setf (symbol-function 'add)
(lambda (n)
(+ (funcall fa n) (funcall ff)))))
This then defines a new function add
which has access to the closure values via the old functions - captured in its own closure.
Style
Don't use LET enclosed DEFUNs:
You can't from the outside.
You could try to provide helper functionality for that in the same lexical scope. This might entail creating an ad hoc function registry therein.
Another way would be to use dynamic variables, but of course that just breaks open the closure.
Maybe relevant (from https://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html):
The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With