From: Dan Bensen
Subject: Trying to redefine a macro
Date: 
Message-ID: <f3228p$615$1@wildfire.prairienet.org>
I'm having trouble redefining my do-hashtable macro
in the sbcl repl without quitting and restarting.

This is in stdlib.l:
...
   (:export ...	:do-hashtable ...)
...
(defmacro do-hashtable ...
...

This is the code that reloads stdlib:
   (when (find-package :stdlib)
     (unuse-package  :stdlib)
     (delete-package :stdlib))
   (load "/usr/home/dan/progg/lib/cl/stdlib.l")
   (use-package :stdlib))

But calling the macro still generates an "undefined function" error:
; in: LAMBDA NIL
;...
; caught STYLE-WARNING:
;   undefined function: DO-HASHTABLE

It's defined, it's exported as a keyword, and I even tried
importing it in the current package (cl-user):

* (eq 'do-hashtable 'stdlib:do-hashtable)
NIL
* (import 'stdlib:do-hashtable)
debugger invoked on a SB-INT:NAME-CONFLICT
...
Select a symbol to be made accessible in package COMMON-LISP-USER:
   1. STDLIB:DO-HASHTABLE
   2. #:DO-HASHTABLE
Enter an integer (between 1 and 2): 1
T
* (eq 'do-hashtable 'stdlib:do-hashtable)
T
* <load a file that calls the macro>
...
; in: LAMBDA NIL
;...
; caught STYLE-WARNING:
;   undefined function: DO-HASHTABLE

-- 
Dan
www.prairienet.org/~dsb/

From: Rainer Joswig
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <joswig-392F9F.21023723052007@news-europe.giganews.com>
In article <············@wildfire.prairienet.org>,
 Dan Bensen <··········@cyberspace.net> wrote:

> I'm having trouble redefining my do-hashtable macro
> in the sbcl repl without quitting and restarting.
> 
> This is in stdlib.l:
> ...
>    (:export ...	:do-hashtable ...)
> ...
> (defmacro do-hashtable ...
> ...
> 
> This is the code that reloads stdlib:
>    (when (find-package :stdlib)
>      (unuse-package  :stdlib)
>      (delete-package :stdlib))
>    (load "/usr/home/dan/progg/lib/cl/stdlib.l")
>    (use-package :stdlib))
> 
> But calling the macro still generates an "undefined function" error:
> ; in: LAMBDA NIL
> ;...
> ; caught STYLE-WARNING:
> ;   undefined function: DO-HASHTABLE
> 
> It's defined, it's exported as a keyword, and I even tried
> importing it in the current package (cl-user):
> 
> * (eq 'do-hashtable 'stdlib:do-hashtable)
> NIL
> * (import 'stdlib:do-hashtable)
> debugger invoked on a SB-INT:NAME-CONFLICT
> ...
> Select a symbol to be made accessible in package COMMON-LISP-USER:
>    1. STDLIB:DO-HASHTABLE
>    2. #:DO-HASHTABLE
> Enter an integer (between 1 and 2): 1
> T
> * (eq 'do-hashtable 'stdlib:do-hashtable)
> T
> * <load a file that calls the macro>
> ...
> ; in: LAMBDA NIL
> ;...
> ; caught STYLE-WARNING:
> ;   undefined function: DO-HASHTABLE


Is the file compiled before?
In which package do you use package STDLIB?
In which package is the macro being used?

Usually one does not delete packages to redefine macros
btw..

-- 
http://lispm.dyndns.org
From: Dan Bensen
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <f3243u$6ja$1@wildfire.prairienet.org>
Rainer Joswig wrote:
> Is the file compiled before?
There are two files, stdlib.l and the file
that uses it.  Both files have been loaded.

> In which package do you use package STDLIB?
> In which package is the macro being used?
Everything except stdlib is in cl-user.

> Usually one does not delete packages to redefine macros
That's left over from when I was exporting symbols in
the wrong package.  Also, some part of that code eliminates
the "STYLE-WARNING: redefining ..." messages when the file
is reloaded after editing.

-- 
Dan
www.prairienet.org/~dsb/
From: Rainer Joswig
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <joswig-5A1B45.21320123052007@news-europe.giganews.com>
In article <············@wildfire.prairienet.org>,
 Dan Bensen <··········@cyberspace.net> wrote:

> Rainer Joswig wrote:
> > Is the file compiled before?
> There are two files, stdlib.l and the file
> that uses it.  Both files have been loaded.
> 
> > In which package do you use package STDLIB?
> > In which package is the macro being used?
> Everything except stdlib is in cl-user.

If you load code with a reference to a package that
is no longer there, you might get an error.
Providing a new package with the same name
might not be enough. You need to recompile/reload the
old code from source.

> 
> > Usually one does not delete packages to redefine macros
> That's left over from when I was exporting symbols in
> the wrong package.  Also, some part of that code eliminates
> the "STYLE-WARNING: redefining ..." messages when the file
> is reloaded after editing.

There should be switches to turn of warnings and messages
from the compiler.

-- 
http://lispm.dyndns.org
From: Dan Bensen
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <f32asc$8ll$1@wildfire.prairienet.org>
Rainer Joswig wrote:
> If you load code with a reference to a package that
> is no longer there, you might get an error.
The file containing the package is loaded and
the packages is use-package'd.

> Providing a new package with the same name
> might not be enough. You need to recompile/reload the
> old code from source.
Right, that's what I'm doing.  The warning occurs
when the file containing the client code is loading.

A couple people have been helping me out on #lisp.
This is what I originally did:
   (unintern 'do-hashtable)
   (import 'stdlib:do-hashtable)
This did NOT work.

This is what Krystof suggested:
   (unintern 'cl-user::do-hashtable)
   (import 'stdlib::do-hashtable "STDLIB")
This DID work.

I'm not sure why those two sequences work differently,
but the second one seems to have conquered the problem.






-- 
Dan
www.prairienet.org/~dsb/
From: Rainer Joswig
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <joswig-260549.11322124052007@news-europe.giganews.com>
In article <············@wildfire.prairienet.org>,
 Dan Bensen <··········@cyberspace.net> wrote:

> Rainer Joswig wrote:
> > If you load code with a reference to a package that
> > is no longer there, you might get an error.
> The file containing the package is loaded and
> the packages is use-package'd.
> 
> > Providing a new package with the same name
> > might not be enough. You need to recompile/reload the
> > old code from source.
> Right, that's what I'm doing.  The warning occurs
> when the file containing the client code is loading.
> 
> A couple people have been helping me out on #lisp.
> This is what I originally did:
>    (unintern 'do-hashtable)
>    (import 'stdlib:do-hashtable)
> This did NOT work.
> 
> This is what Krystof suggested:
>    (unintern 'cl-user::do-hashtable)

It is good to give both the package and the symbol.

To avoid any interaction with the reader I usually
use something like this:

(let ((symbol (find-symbol "DO-HASHTABLE" "CL-USER")))
  (when symbol
     (unintern symbol "CL-USER")))

Also note that you can use UNINTERN to remove the
home package of a symbol, and still it
can be accessible in another package.


>    (import 'stdlib::do-hashtable "STDLIB")

This looks weird. ;-) You are importing a symbol
into the package of that symbol? Something
must be broken in your code. The only reason I can imagine
to use above code is when the STDLIB package
at read time is a different package from
the STDLIB package at runtime. But then
you are already shooting yourself in the foot. ;-)
Literally.

> This DID work.
> 
> I'm not sure why those two sequences work differently,
> but the second one seems to have conquered the problem.

-- 
http://lispm.dyndns.org
From: Dan Bensen
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <f354hr$5bm$1@wildfire.prairienet.org>
Rainer Joswig wrote:
 > It is good to give both the package and the symbol.
What does the reader interpret 'foo as, if not
'current-package::foo?

 > The only reason I can imagine to use above code is
 > when the STDLIB package at read time is a different
 > package from the STDLIB package at runtime.
All I know is that cl-user still seemed to be using an
old symbol from the library package, even after reloading
the package source and re-using the package, and then
reloading the client source in cl-user.  It looks like
putting "cl-user::" in the unintern form may have made
the difference, but I don't understand why.  Thanks for
helping.

-- 
Dan
www.prairienet.org/~dsb/
From: Thomas A. Russ
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <ymips4jvbjw.fsf@sevak.isi.edu>
Dan Bensen <··········@cyberspace.net> writes:

> Rainer Joswig wrote:

> All I know is that cl-user still seemed to be using an
> old symbol from the library package, even after reloading
> the package source and re-using the package, and then
> reloading the client source in cl-user.

I think you still have some residual confusion about how the package
system works.  There will only be a SINGLE (interned) symbol with a
given print name in a particular package.  Reloading code that refers to
that symbol will refer to the same symbol, so there really isn't any
notion of "old" or "new" symbols, unless you start doing strange things
like uninterning symbols or deleting packages.

But you shouldn't really be doing that, since it violates some nice
features of lisp, namely that you can normally rely on (interned)
symbols retaining their identity across files and loading of code.  By
trying to circumvent this invariant, you are making debugging your
original problem much, much harder.  Don't muck with the packages.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Dan Bensen
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <f3hujs$lv5$1@wildfire.prairienet.org>
Thomas A. Russ wrote:
> Dan Bensen <··········@cyberspace.net> writes:
>> All I know is that cl-user still seemed to be using an
>> old symbol from the library package, even after reloading
>> the package source and re-using the package, and then
>> reloading the client source in cl-user.

> I think you still have some residual confusion about how the package
> system works.  There will only be a SINGLE (interned) symbol with a
> given print name in a particular package.  Reloading code that refers to
> that symbol will refer to the same symbol, so there really isn't any
> notion of "old" or "new" symbols, unless you start doing strange things
> like uninterning symbols or deleting packages.

Dan Bensen wrote:
 > This is the code that reloads stdlib:
 >   (when (find-package :stdlib)
 >     (unuse-package  :stdlib)
 >     (delete-package :stdlib))
 >   (load "/usr/home/dan/progg/lib/cl/stdlib.l")
 >   (use-package :stdlib))

:D

> But you shouldn't really be doing that, since it violates some nice
> features of lisp, namely that you can normally rely on (interned)
> symbols retaining their identity across files and loading of code.  By
> trying to circumvent this invariant, you are making debugging your
> original problem much, much harder.  Don't muck with the packages.

Okay, but I still want to muck with their symbols, or do something
with them to accommodate changes in other packages.  In recent projects,
I've been making a load.l file to manage reloading files after editing
them, and I want to suppress the resulting redefinition errors, and of
course update any client code that's affected.

-- 
Dan
www.prairienet.org/~dsb/
From: Thomas A. Russ
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <ymi7iqquu39.fsf@sevak.isi.edu>
Dan Bensen <··········@cyberspace.net> writes:

> Thomas A. Russ wrote:
> > I think you still have some residual confusion about how the package
> > system works.  There will only be a SINGLE (interned) symbol with a
> > given print name in a particular package.  Reloading code that refers to
> > that symbol will refer to the same symbol, so there really isn't any
> > notion of "old" or "new" symbols, unless you start doing strange things
> > like uninterning symbols or deleting packages.
> 
> Dan Bensen wrote:
>  > This is the code that reloads stdlib:
>  >   (when (find-package :stdlib)
>  >     (unuse-package  :stdlib)
>  >     (delete-package :stdlib))
>  >   (load "/usr/home/dan/progg/lib/cl/stdlib.l")
>  >   (use-package :stdlib))
> 
> :D

Yes, I remember.  That's why I put the caveat in my reply ;)

> > But you shouldn't really be doing that, since it violates some nice
> > features of lisp, namely that you can normally rely on (interned)
> > symbols retaining their identity across files and loading of code.  By
> > trying to circumvent this invariant, you are making debugging your
> > original problem much, much harder.  Don't muck with the packages.
> 
> Okay, but I still want to muck with their symbols, or do something
> with them to accommodate changes in other packages.  In recent projects,
> I've been making a load.l file to manage reloading files after editing
> them, and I want to suppress the resulting redefinition errors, and of
> course update any client code that's affected.

Well, it will be easier to update affected client code if you don't
introduce new symbols.  The client code refers to a particular symbol
and won't reparse its reference if you start getting rid of it.  It will
just refer to some presumably now uninterned symbol.

Certainly with functions, you WANT to retain the same symbol so that
Lisp's dynamic linker can make the new function definition available to
any code that depends on it.  Macros are trickier, since they require
the code in question to be re-compiled in order to guarantee that the
new definition takes effect.  Certainly systems like DEFSYSTEM and ASDF
are designed to manage such dependencies.

I think that if you muck with the symbols, you will find a lot of things
to be really difficult to get working, as well as making for bugs that
are really hard to track down.

As for redefinition warnings, you can use a more specific solution to
stop those from bothering you.  I posted examples from a number of lisp
systems already.  You should be able to find something that works for
your lisp implementation as well.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Drew McDermott
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <1180117026.657976.91730@u30g2000hsc.googlegroups.com>
On May 23, 5:20 pm, Dan Bensen <··········@cyberspace.net> wrote:
> This is what Krystof suggested:
>    (unintern 'cl-user::do-hashtable)
>    (import 'stdlib::do-hashtable "STDLIB")
> This DID work.

As soon as you type "stdlib::do-hashtable" the symbol is created in
the :stdlib package, so importing it is a no-op (as Rainer Joswig
said).  If you really want to create the symbol by evaluating
something, try (intern "DO-HASHTABLE" :stdlib).  (Or "STDLIB", but I
hate typing uppercase to Lisp for purely historical reasons.  That is,
it's typing uppercase only for historical reasons that I hate.)

    -- Drew McDermott
From: Thomas A. Russ
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <ymify5mvyyp.fsf@sevak.isi.edu>
Dan Bensen <··········@cyberspace.net> writes:

> I'm having trouble redefining my do-hashtable macro
> in the sbcl repl without quitting and restarting.

Well, that seems a little bit drastic.

> This is in stdlib.l:
> ...
>    (:export ...	:do-hashtable ...)
> ...
> (defmacro do-hashtable ...
> ...

OK.  That seems fine.

> This is the code that reloads stdlib:
>    (when (find-package :stdlib)
>      (unuse-package  :stdlib)
>      (delete-package :stdlib))
>    (load "/usr/home/dan/progg/lib/cl/stdlib.l")
>    (use-package :stdlib))

This seems tremendous overkill.  You shouldn't really be deleting the
package.  Remember, in lisp the package only defines the namespace.  It
does not affect other things.  You should be able to redefine functions
and macros simply by reloading the file.  In other words, replace what
you have above with:

  (load "/usr/home/dan/progg/lib/cl/stdlib.l")

When you delete packages, you can end up stranding symbols in that
package that are referenced from elsewhere.  In particular, if some
other package is using or has imported symbols from your deleted
package, they are still around.  Deleting a package doesn't somehow
magically get rid of the symbols in it.

I suspect that if you have to quit and restart, it is largely because
you have managed to screw up your namespaces and symbol tables.  So
don't delete packages!

> But calling the macro still generates an "undefined function" error:
> ; in: LAMBDA NIL
> ;...
> ; caught STYLE-WARNING:
> ;   undefined function: DO-HASHTABLE
> 
> It's defined, it's exported as a keyword, and I even tried
> importing it in the current package (cl-user):

Well, the problem is likely related to messing up your package system.
That is one of the few things that can really require restarting your
lisp system.

> * (eq 'do-hashtable 'stdlib:do-hashtable)
> NIL
> * (import 'stdlib:do-hashtable)
> debugger invoked on a SB-INT:NAME-CONFLICT
> ...
> Select a symbol to be made accessible in package COMMON-LISP-USER:
>    1. STDLIB:DO-HASHTABLE
>    2. #:DO-HASHTABLE
> Enter an integer (between 1 and 2): 1
> T
> * (eq 'do-hashtable 'stdlib:do-hashtable)
> T
> * <load a file that calls the macro>
> ...
> ; in: LAMBDA NIL
> ;...
> ; caught STYLE-WARNING:
> ;   undefined function: DO-HASHTABLE
> 
> -- 
> Dan
> www.prairienet.org/~dsb/

Now, it is important to remember that redefining a macro doesn't work
the same way as redefining a function.  If you redefine a function, then
all code that uses that function get the new definition.  Code that uses
a macro doesn't have the macro call anymore (since the evaluator or
compiler has expanded it away), so you will have to reload or recompile
the source code that uses a macro.

Some examples:

(defun f1 () (print "First"))
(compile 'f1)
(defun f2 () (f1) 'f2)
(compile 'f2)

(f2)  =>  prints "First"  and returns F2

(defun f1 () (print "Second"))
(compile 'f1)

(f2)  =>  prints "Second"  and returns F2

----------------

(defmacro m1 () '(print "First"))
(defun f3 () (m1) 'f3)
(compile 'f3)

(f3)  =>  prints "First"  and returns F3

(defmacro m1 () '(print "Second"))

In compiled code, this will do the following.  In interpreted code, it
is actually implementation dependent on what it will do.

(f3)  =>  prints "First"  and returns F3
          because M1 in the body of F3 has already been expanded.

(defun f3 () (m1) 'f3)
(compile 'f3)
   ;; This now causes the new expansion to be used.

(f3)  =>  prints "Second"  and returns F3

--------------------



-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Dan Bensen
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <f3554c$5i1$1@wildfire.prairienet.org>
Thomas A. Russ wrote:
> You shouldn't really be deleting the package.
It eliminated the "STYLE-WARNING: redefining FOO-FUNCTION in DEFUN"
messages when loading the file.  I want to suppress those but still
get other style warnings.

-- 
Dan
www.prairienet.org/~dsb/
From: Thomas A. Russ
Subject: Re: Trying to redefine a macro
Date: 
Message-ID: <ymi7iqwwg0l.fsf@sevak.isi.edu>
Dan Bensen <··········@cyberspace.net> writes:

> Thomas A. Russ wrote:
> > You shouldn't really be deleting the package.
> It eliminated the "STYLE-WARNING: redefining FOO-FUNCTION in DEFUN"
> messages when loading the file.  I want to suppress those but still
> get other style warnings.

There's usually a better, more specific method to do this.  It varies a
bit depending on the lisp implementation, though.  Here are some ways of
doing that:



;;;; WITH-REDEFINITION-WARNINGS-SUPPRESSED

#+:MCL
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((CCL::*warn-if-redefine* nil))
     ,@forms ))

#+:EXCL
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((EXCL::*redefinition-warnings* nil))
     ,@forms ))

#+:ACLPC
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((top::*warn-on-redefinition* nil))
     ,@forms ))

#+:LUCID
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((USER::*redefinition-action* nil))
     ,@forms ))

#+:TI
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((TICL::inhibit-fdefine-warnings t))
     ,@forms ))

#+:LISPWORKS
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  `(let ((LISPWORKS::*redefinition-action* nil))
     ,@forms ))

#-(or :MCL :EXCL :ACLPC :LUCID :TI :LISPWORKS)
(defmacro with-redefinition-warnings-suppressed (&body forms)
  ;; Wrap form with code to suppress redefinition warnings
  ;; Default: Do nothing:
  `(progn ,@forms ))



-- 
Thomas A. Russ,  USC/Information Sciences Institute