From: David Fisher
Subject: code replacement
Date: 
Message-ID: <14030ca9.0403112325.2dfd99ae@posting.google.com>
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?

From: Kenny Tilton
Subject: Re: code replacement
Date: 
Message-ID: <0ve4c.15760$c73.5052954@twister.nyc.rr.com>
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
From: Raymond Wiker
Subject: Re: code replacement
Date: 
Message-ID: <86hdwufp04.fsf@raw.grenland.fast.no>
·············@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/
From: Alexey Dejneka
Subject: Re: code replacement
Date: 
Message-ID: <m3y8q574b5.fsf@comail.ru>
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