From: Robert Ewald
Subject: Keeping the image and the lisp files in sync
Date: 
Message-ID: <ovSdnURet4niz3fVnZ2dnUVZ8gidnZ2d@lyse.net>
...Delurking...

Hello,

I have constant trouble keeping my Lisp programs loadable. I hack away for a
while and everything works beautifully. The flow is great and I feel good.
Then the next day after I had turned off my PC for the night, nothing
works. The problem is of course that the files are not in the right order,
or missing in the .asd file. Deleted or renamed functions and methods
weren't renamed in every place and so on.

I handle this problem now by frequent restart-inferior-lisp and reloading
my .asd file. But this is not exactly satisfactory. It breaks the flow and
makes the REPL not such a great tool any longer.

I wonder if I am missing something. Is there some support in finding out
that a function or method is no longer defined in the source? 
I suppose finding the dependencies is a bit more tricky.
Please share your ways to deal with that sort of situation.

Thanks.
-- 
Robert Ewald

From: Alessio Stalla
Subject: Re: Keeping the image and the lisp files in sync
Date: 
Message-ID: <d2207fb3-7bd0-4ceb-bb74-62aa77ee8a70@p59g2000hsd.googlegroups.com>
On 6 Ott, 20:01, Robert Ewald <···················@gmx.net> wrote:
> ...Delurking...
>
> Hello,
>
> I have constant trouble keeping my Lisp programs loadable. I hack away for a
> while and everything works beautifully. The flow is great and I feel good.
> Then the next day after I had turned off my PC for the night, nothing
> works. The problem is of course that the files are not in the right order,
> or missing in the .asd file. Deleted or renamed functions and methods
> weren't renamed in every place and so on.
>
> I handle this problem now by frequent restart-inferior-lisp and reloading
> my .asd file. But this is not exactly satisfactory. It breaks the flow and
> makes the REPL not such a great tool any longer.
>
> I wonder if I am missing something. Is there some support in finding out
> that a function or method is no longer defined in the source?
> I suppose finding the dependencies is a bit more tricky.
> Please share your ways to deal with that sort of situation.
>
> Thanks.
> --
> Robert Ewald

The same thing used to happen to me quite frequently, and it still
happens from time to time. I have learned not to edit things directly
at the REPL, but rather use my editor (Emacs + SLIME or the LispWorks
IDE) to edit the source files and then evaluate the new definitions
into the Lisp image. That way the files are kept more or less
constantly in sync with the image. As for "refactoring" (e.g. changing
names to functions/methods or deleting them), I do it by hand when
it's simple, or I use the cross-reference functionality of my editor
to see who calls who etc. From time to time a restart of the image is
still necessary because some things are not easily undoable, e.g. if
you do

(let ((x #'some-function))
  (lambda (k) (funcall x k)))

and then redefine some-function, the closure will still refer to the
old definition.

Also, check out http://www.informatimago.com/develop/lisp/small-cl-pgms/ibcl/index.html
by Pascal Bourguignon. I have never used it, but it looks very
interesting and I'll try it out sooner or later.

hth,

Alessio Stalla
From: Kenny
Subject: Re: Keeping the image and the lisp files in sync
Date: 
Message-ID: <48ea736f$0$4967$607ed4bc@cv.net>
Robert Ewald wrote:
> ...Delurking...
> 
> Hello,
> 
> I have constant trouble keeping my Lisp programs loadable. I hack away for a
> while and everything works beautifully. The flow is great and I feel good.
> Then the next day after I had turned off my PC for the night, nothing
> works. The problem is of course that the files are not in the right order,
> or missing in the .asd file. Deleted or renamed functions and methods
> weren't renamed in every place and so on.
> 
> I handle this problem now by frequent restart-inferior-lisp and reloading
> my .asd file. But this is not exactly satisfactory. It breaks the flow and
> makes the REPL not such a great tool any longer.
> 
> I wonder if I am missing something. Is there some support in finding out
> that a function or method is no longer defined in the source? 
> I suppose finding the dependencies is a bit more tricky.
> Please share your ways to deal with that sort of situation.

Experience helps. I have a second sense now as to when it is time to do 
what you have already figured out, namely to bounce my Lisp so I find 
all this stuff. And I always start fresh at least every day. Experience 
will also reduce to 3 seconds the amount of time it takes to figure out 
that something went wrong because of a bounce, and it will lead you to 
Always Update your asd rather than put it off.

hth,kt
From: Pascal J. Bourguignon
Subject: Re: Keeping the image and the lisp files in sync
Date: 
Message-ID: <87vdw58ted.fsf@hubble.informatimago.com>
Robert Ewald <···················@gmx.net> writes:

> ...Delurking...
>
> Hello,
>
> I have constant trouble keeping my Lisp programs loadable. I hack away for a
> while and everything works beautifully. The flow is great and I feel good.
> Then the next day after I had turned off my PC for the night, nothing
> works. The problem is of course that the files are not in the right order,
> or missing in the .asd file. Deleted or renamed functions and methods
> weren't renamed in every place and so on.
>
> I handle this problem now by frequent restart-inferior-lisp and reloading
> my .asd file. But this is not exactly satisfactory. It breaks the flow and
> makes the REPL not such a great tool any longer.
>
> I wonder if I am missing something. Is there some support in finding out
> that a function or method is no longer defined in the source? 
> I suppose finding the dependencies is a bit more tricky.
> Please share your ways to deal with that sort of situation.

When you rename a function, use SUBST:


C/IBCL-USER[86]> (defun old-name (x)
                   (cond ((= 1 x)  :done)
                         ((oddp x) (old-name (1+ (* 3 x))))
                         ( t       (old-name (/ x 2)))))
OLD-NAME
C/IBCL-USER[87]> (third (get-source 'old-name))
(DEFUN OLD-NAME (X)
 (COND ((= 1 X) :DONE) ((ODDP X) (OLD-NAME (1+ (* 3 X)))) (T (OLD-NAME (/ X 2)))))
C/IBCL-USER[88]> (subst 'new-name 'old-name (third (get-source 'old-name)))
(DEFUN NEW-NAME (X)
 (COND ((= 1 X) :DONE) ((ODDP X) (NEW-NAME (1+ (* 3 X)))) (T (NEW-NAME (/ X 2)))))
C/IBCL-USER[89]> (eval (subst 'new-name 'old-name (third (get-source 'old-name))))
NEW-NAME
C/IBCL-USER[90]> (new-name 42)
:DONE
C/IBCL-USER[91]> 


In general, using a smart editor can help.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Logiciels libres : nourris au code source sans farine animale."
From: Rainer Joswig
Subject: Re: Keeping the image and the lisp files in sync
Date: 
Message-ID: <joswig-EC58AD.21481106102008@news-europe.giganews.com>
In article <································@lyse.net>,
 Robert Ewald <···················@gmx.net> wrote:

> ...Delurking...
> 
> Hello,
> 
> I have constant trouble keeping my Lisp programs loadable. I hack away for a
> while and everything works beautifully. The flow is great and I feel good.
> Then the next day after I had turned off my PC for the night, nothing
> works. The problem is of course that the files are not in the right order,
> or missing in the .asd file. Deleted or renamed functions and methods
> weren't renamed in every place and so on.
> 
> I handle this problem now by frequent restart-inferior-lisp and reloading
> my .asd file. But this is not exactly satisfactory. It breaks the flow and
> makes the REPL not such a great tool any longer.

the old InterLisp-D system was working directly from the image,
like the Smalltalk systems. No wonder, since both InterLisp-D
and Smalltalk came from Xerox.

The MIT tradition is different and more based on REPLs and files.

Pascal mentioned it already - I'll just add my wording:

there are several ways to work interactively with Lisp.

One way is to use the REPL:

* type definitions to the Listener (the Read Eval Print Loop).
  copy thinks you like to an editor buffer and edit
  it into a working file. try out new stuff in the Listener
  and update the Editor

A typical way is to use mostly the Editor:

* type definitions in the editor and compile/evaluate from there.
  Some Lisp systems evaluate/compile directly. Macintosh Common Lisp
  was nice, it enqueued the forms into the top listener and it
  was evaluated/compiled in the listener. Which makes results
  and variables like *, **, *** and others available in the listener.

  While you are editing in the Editor, you try to maintain the
  structure of a working and loadable file. Example code is placed into
  comments or special test forms and executed from there.

  Some Lisp systems track also what you edit and allow you
  to compile only the changed code. So you can make
  a bunch of edits to different functions in your editor,
  press a key and all the changes are compiled.

  LispWorks for example has a tab in the editor for
  changed definitions (means definitions that have
  been edited since the last save, the last compile, first edit).
  LispWorks also has a command 'M-x compile changed definitions'.
  Stuff like that helps using the editor for editing code
  (instead of using the Listener to edit code) and
  compiling from there.

  Still after some development cycle you need to see if the
  thing compiles with a fresh new Lisp by compiling/loading
  the files (usually using some of the system tools).

The next step is to base your editing on a system. Some Lisps
allow you for example to restrict some editor commands (searches, ...)
to a certain system. You tell the editor to edit a system - it will
load all the corresponding source files into the editor.
You can now make changes and compile the changes from the editor.
But then you compile a system and the Lisp system shows a bunch
of warnings and errors. You can now take this warnings/error list
and work on it, the editor will locate the source of the warning/error.
You will change it and the editor will remove the warning/error
when the form in question compiles without warnings/errors.
LispWorks for example allows that by using the 'Compilation
Conditions Browser'.

Another step from there is to write 'patches' to update
both the sources and the Lisp system state. That's for example
what the Lisp Machine uses for its system construction tool (SCT).
Typically the files are there to load a base of the software
and then it loads incremental patches to make changes to the loaded
software. If one wants, say, to add a new command to a graphics
editor, one edits the file with the commands, tries the command
and if it works fine, the corresponding Lisp forms will be
added to a patch file, which then can be loaded on top of
the loaded graphics editor to provide the new functionality.
This makes it possible to patch saved images which already
contain some version of the software without compiling/loading
everything again.

Above I have described three ways to use a Lisp system interactively.
None of those will magically keep the system sources in sync with what
is in the running Lisp, but the more advanced ways will make
it easier by introducing some discipline.

1) work mostly in the REPL
2) work mostly in the editor with source files
2a) work mostly in the editor and use editor support for tracking
    errors and changes in files and systems
3) work mostly with system level commands from the editor or the listener

I usually use 2 and switch to 2a or 3 when the code structure
becomes more stable. For inspecting data and throw-away-code
I often just use the Listener (and related tools).

> I wonder if I am missing something. Is there some support in finding out
> that a function or method is no longer defined in the source? 

Some Lisp systems allow you to directly undefine from
the editor. Move to a DEFUN, undefine and delete it then.
LispWorks for example has 'm-x undefine region', which
will show a list of definitions in a region and will
then undefine the selected ones.

> I suppose finding the dependencies is a bit more tricky.
> Please share your ways to deal with that sort of situation.
> 
> Thanks.

-- 
http://lispm.dyndns.org/