Let's say I'm doing a long calculation that involves frequent calls to
a referentially transparent function FOO. In the middle of the
calculation, I decide that I want to change the definition of the
function (make it more efficient, or add debug statements, whatever).
Exactly how can this be done?
One problem is that while the program is still running, the listener
isn't really listening to you. Should I use threads? How? Post a
working example if you know, but assume that you didn't know *in*
*advance* that you would be replacing FOO specifically.
What will be different if FOO is not a function, but a class, struct
or a generic function with a different signature?
David Fisher wrote:
> Let's say I'm doing a long calculation that involves frequent calls to
> a referentially transparent function FOO. In the middle of the
> calculation, I decide that I want to change the definition of the
> function (make it more efficient, or add debug statements, whatever).
> Exactly how can this be done?
Just do it.
>
> One problem is that while the program is still running, the listener
> isn't really listening to you.
Mine is. I use AllegroCL on win32. Usually I have landed in a backtrace
when I go redefine something, but there have been those amazing moments
when I could get to the listener and nothing else and was aboe to set a
backdoor global var I have for prtty much this purpose. I call it *stop*.
I think I have in the same situation managed to redefine a function such
that I could escape some loop. But as you say, I gotta get to the IDE first.
Should I use threads? How? Post a
> working example if you know, but assume that you didn't know *in*
> *advance* that you would be replacing FOO specifically.
Right, you do not have to know in advance. I seem to recall Corman doc
suggesting running win32 GDI apps in a thread for this reason. But this
is implementation dependent and you neglected to fill us in on your
environment: OS, Lisp implementation, versions thereof, coming from
emacs or not, etc etc.
>
> What will be different if FOO is not a function, but a class, struct
> or a generic function with a different signature?
Class, OK. Struct, forget it. Changing a GF and all the code that uses
that and all the methods? I have refactored for hours before resuming
from a backtrace. No problemo, unless existing instances need a once-off
update-instance-for-redefined-class, then I just kill the backtrace and
star over.
kt
--
http://tilton-technology.com
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
·············@yahoo.com (David Fisher) writes:
> Let's say I'm doing a long calculation that involves frequent calls to
> a referentially transparent function FOO. In the middle of the
> calculation, I decide that I want to change the definition of the
> function (make it more efficient, or add debug statements, whatever).
> Exactly how can this be done?
Break execution, replace the function, continue.
Example using sbcl:
Script started on Fri Mar 12 09:19:28 2004
···@raw (vm) $ sbcl
This is SBCL 0.8.8.3, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (defun testit ()
(format t "foo!~%")
(sleep 1)
(testit))
TESTIT
* (testit)
foo!
foo!
^C
debugger invoked on a SIMPLE-CONDITION in thread 75133:
interrupted at #X280CCBE0
You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE] Return from SB-UNIX:SIGINT.
1: [ABORT ] Reduce debugger level (leaving debugger, returning to toplevel).
2: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop.
("foreign function call land: ra=#x8054D11")
0] (defun testit ()
(format t "bar!~%")
(sleep 1)
(testit))
STYLE-WARNING: redefining TESTIT in DEFUN
TESTIT
0] 0
bar!
bar!
bar!
> One problem is that while the program is still running, the listener
> isn't really listening to you. Should I use threads? How? Post a
> working example if you know, but assume that you didn't know *in*
> *advance* that you would be replacing FOO specifically.
The example above does not require threads. It *does* require
that the function to be replaced is called at some point (i.e, if I
had written testit as a loop instead of a recursive function, it would
not have worked.)
> What will be different if FOO is not a function, but a class, struct
> or a generic function with a different signature?
You can't redefine a struct. If you redefine a class, you
should define methods for update-class-for-redefined-class. If you
want to change a function signature (generic function or not), you
may also need to change all callers (depending on the actual
difference; if it's just in &optional or &key parameters, you may not
need to change the callers.)
If you change a generic function signature, you'll also need
to update all methods.
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
Raymond Wiker <·············@fast.no> writes:
> ·············@yahoo.com (David Fisher) writes:
>
> > Let's say I'm doing a long calculation that involves frequent calls to
> > a referentially transparent function FOO. In the middle of the
> > calculation, I decide that I want to change the definition of the
> > function (make it more efficient, or add debug statements, whatever).
> > Exactly how can this be done?
>
> Break execution, replace the function, continue.
>
> Example using sbcl:
[snip]
> * (defun testit ()
> (format t "foo!~%")
> (sleep 1)
> (testit))
>
> TESTIT
> * (testit)
> foo!
> foo!
> ^C
> debugger invoked on a SIMPLE-CONDITION in thread 75133:
> interrupted at #X280CCBE0
[snip]
> 0] (defun testit ()
> (format t "bar!~%")
> (sleep 1)
> (testit))
>
> STYLE-WARNING: redefining TESTIT in DEFUN
> TESTIT
> 0] 0
> bar!
You should define TESTIT this way:
(defun testit ()
(declare (notinline testit))
(format t "foo!~%")
(sleep 1)
(testit))
Otherwise, if (> (max speed space) debug) [to be more precise, if
RECOGNIZE-SELF-CALLS is on, as reported by
SB-EXT:DESCRIBE-COMPILER-POLICY], SBCL will use the direct call in
TESTIT and the redefinition will not work.
--
Regards,
Alexey Dejneka
"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer