For instance I have this package definition which shadows COMMON-LISP:LISTEN :
(defpackage :shadows
  (:use :common-lisp)
  (:shadow #:listen)
  (:export #:listen))
And then I want to use this package from another package, say
(defpackage :light
  (:use :common-lisp
        :shadows))
What is the purpose of shadow if I cannot actually override Common Lisp symbols when using the package ?
The :shadow argument to defpackage
affects the definition of the package shadows,
not the later use of shadows in light.
You need to use shadowing-import:
(defpackage #:shadows
  (:use #:common-lisp)
  (:shadow #:listen)
  (:export #:listen))
(defpackage #:light
  (:shadowing-import-from #:shadows #:listen)
  (:use #:common-lisp #:shadows))
(eq 'light::listen 'shadows:listen)
==> T
(describe 'light::listen)
==>
SHADOWS:LISTEN is the symbol SHADOWS:LISTEN, lies in #<PACKAGE SHADOWS>,
is accessible in 2 packages LIGHT, SHADOWS.
 #<PACKAGE SHADOWS> is the package named SHADOWS.
 It imports the external symbols of 1 package COMMON-LISP and
 exports 1 symbol to 1 package LIGHT.
If you need to do bulk shadowing, you would need to use individual functions
(make-package,
 import,
 export,
 shadow,
 use-package):
(defparameter *my-shadow-list* '(#:car #:cdr))
(make-package '#:my-package :use nil)
(import *my-shadow-list* '#:my-package)
(export *my-shadow-list* '#:my-package)
(shadow *my-shadow-list* '#:my-package)
(use-package '#:cl '#:my-package)
(make-package '#:my-user)
(shadowing-import *my-shadow-list* '#:my-user)
(use-package '(#:cl #:my-package) '#:my-user)
(describe 'my-user::car)
==>
MY-PACKAGE:CAR is the symbol MY-PACKAGE:CAR, lies in #<PACKAGE MY-PACKAGE>,
is accessible in 2 packages MY-PACKAGE, MY-USER.
 #<PACKAGE MY-PACKAGE> is the package named MY-PACKAGE.
 It imports the external symbols of 1 package COMMON-LISP and
 exports 2 symbols to 1 package MY-USER.
You might find macroexpand-1 useful in decising how get where you need to go:
(macroexpand-1 '(defpackage #:light
                 (:shadowing-import-from #:shadows #:listen)
                 (:use #:common-lisp #:shadows)))
==>
(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE)
 (SYSTEM::%IN-PACKAGE "LIGHT" :NICKNAMES 'NIL :USE 'NIL :CASE-SENSITIVE NIL
  :CASE-INVERTED NIL)
 (SYSTEM::SHADOWING-IMPORT-CERROR "LISTEN" "SHADOWS" NIL "LIGHT")
 (USE-PACKAGE '("COMMON-LISP" "SHADOWS") "LIGHT") (FIND-PACKAGE "LIGHT")) ;
T
PS. Shadowing ANSI CL standard names is not a very good idea for your code readability.
OK so there actually is a handy way to do this.
In my many-shadows package I export a shadowing-import-from function. It looks like this :
(defun shadowing-import-from ()
  `(:shadowing-import-from :many-shadows
     ,@(package-shadowing-symbols :many-shadows)))
And then, in the light defpackage I just READ-EVAL it :
(defpackage :light
  (:use :common-lisp
        :many-shadows)
  #.(many-shadows:shadowing-import-from))
So it is explicit that something was shadowed and that I want to use the symbols from many-shadows in priority. And it is short enough to be documented and used pragmatically.
Thank you @sds for pointing me to :shadowing-import-from.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With