Hi all,
I need to shadow some function names so I can use them in place of some
built in CMUCL names, in particular AUTHOR. What's wrong with this
approach:
z.lisp:
(defpackage :pkg
(:use :cl :cl-user))
(in-package pkg)
(export 'author)
(defun author () "test fn")
Now start a lisp session with (load "z.lisp"), and to see why we need a fix:
* (use-package 'pkg)
Error in function use-package:
Use'ing package PKG results in name conflicts for these symbols:
(author)
OK so start again with (load "z.lisp"):
* (shadowing-import 'author)
t
* (use-package 'pkg)
t
* (author)
;
; Warning: This function is undefined:
; author
Error in kernel:%coerce-to-function: the function author is undefined.
Restarts:
0: [abort] Return to Top-Level.
Debug (type H for help)
(kernel:%coerce-to-function author)
Source:
; File: target:code/fdefinition.lisp
(error 'undefined-function :name name)
I can only access the function as (pkg:author), as if the symbol in this
package was never "used." It seems I can only use pkg:author as part of
CL-USER if I first unintern AUTHOR, i.e.:
* (unintern 'author)
t
* (load "z.lisp")
; Loading #p"/home/adam/t/z.lisp".
t
* (use-package 'pkg)
t
* (author)
"test fn"
Thanks,
Adam
Adam Warner <······@consulting.net.nz> wrote in message news:<······························@consulting.net.nz>...
> Hi all,
>
> I need to shadow some function names so I can use them in place of some
> built in CMUCL names, in particular AUTHOR. What's wrong with this
> approach:
>
> z.lisp:
> (defpackage :pkg
> (:use :cl :cl-user))
> (in-package pkg)
> (export 'author)
> (defun author () "test fn")
>
> Now start a lisp session with (load "z.lisp"), and to see why we need a fix:
> * (use-package 'pkg)
>
> Error in function use-package:
> Use'ing package PKG results in name conflicts for these symbols:
> (author)
>
> OK so start again with (load "z.lisp"):
> * (shadowing-import 'author)
>
Here's the problem. You aren't using 'pkg' yet, so the symbol
referred to in the 'shadowing-import' expression is the 'author'
inherited from whatever package it lives in --- i.e., exactly the one
you don't want. Let's call that package 'wckd'. What you're telling
the system is: Put wckd:author in the current package, and don't let
any other package try to override it.
> t
> * (use-package 'pkg)
>
It faithfully carries out your request, silently squelching the
attempt to inherit pkg:author.
> t
> * (author)
> ;
This means (wckd:author)...
>
> ; Warning: This function is undefined:
> ; author
>
... which is undefined.
> I can only access the function as (pkg:author), as if the symbol in this
> package was never "used." It seems I can only use pkg:author as part of
> CL-USER if I first unintern AUTHOR, i.e.:
...
The right thing to do is simply replace the shadowing-import statement
with
(shadowing-import 'pkg:author)
Now it's 'wckd:author' who is left out in the cold.
-- Drew McDermott
Hi Drew McDermott,
> The right thing to do is simply replace the shadowing-import statement
> with
>
> (shadowing-import 'pkg:author)
>
> Now it's 'wckd:author' who is left out in the cold.
I now understand that I instructed the implementation to preserve
CL-USER::AUTHOR since the shadowing-import statement was necessarily
included before use-package was in effect. Using this expression I see it
was likely imported from ASDF (and highlights the use of string
designators): (do-all-symbols (s) (when (string= s "AUTHOR") (print s)))
Thanks for the helpful explanation.
Regards,
Adam
> Using this expression I see it was likely imported from ASDF (and
> highlights the use of string designators): (do-all-symbols (s) (when
> (string= s "AUTHOR") (print s)))
I was mistaken about its origin. I should have started CMUCL with -noinit.
Turns out I had interned the symbol AUTHOR in one of the files I load in
.cmucl-init.lisp.
Regards,
Adam
Adam Warner <······@consulting.net.nz> writes:
> (do-all-symbols (s) (when (string= s "AUTHOR") (print s)))
(find-all-symbols "AUTHOR") runs faster, at least on CMUCL.
In article <······························@consulting.net.nz>, Adam Warner wrote:
> Hi all,
>
> I need to shadow some function names so I can use them in place of some
> built in CMUCL names, in particular AUTHOR. What's wrong with this
> approach:
>
> z.lisp:
> (defpackage :pkg
> (:use :cl :cl-user))
> (in-package pkg)
> (export 'author)
> (defun author () "test fn")
>
My install of CMUCL (18c) doesn't include any symbol AUTHOR visible in
either CL, CL-USER, or EXTENSIONS package.
I will answer by pretending it's EXTENSIONS::DELQ that you want to
shadow and replace, while retaining unqualified access to everything
else from EXTENSIONS. I don't recommend USEing CL-USER since there is
no telling what kind of useless junk is there, and nothing dependably
useful there.
I suggest you use:
z.lisp:
(in-package :user)
(defpackage :pkg
(:use :cl :extensions)
(:shadow #:delq)
(:export #:delq)
)
(in-package :pkg)
(defun delq ()
"test fn")
This says:
My package PKG will take everything from CL and EXTENSIONS, but will
create my own DELQ (shadow) and export it (not strictly required by
your specification; so omit if desired). I can still access
EXTENSIONS:DELQ, but in PKG, unqualified DELQ means the local symbol.
Andrew