[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: OK, so I have a package reference in my init file...



    Date: Mon, 4 Jun 90 22:19 EDT
    From: pan@Athena.Pangaro.Dialnet.Symbolics.Com (Paul Pangaro)

    This also works, as it turns out (I had logical sense reversed when
    debugging, sorry) .....

    (when (find-package 'fred)
     (sct:pkg-bind 'fred (setq foo nil)))   ; really fred:foo

This can't possibly work.  By the time the PKG-BIND is actually doing
anything, the entire form has already been read using whatever package is in
effect in the dynamic environment.  For example, 

   (symbol-package (global:pkg-bind 'mailer 'mumble))
=> #<Package USER (really COMMON-LISP-USER) 42204076>

If you want things to "work", you have to say something like

   (when (find-package 'fred)
     (sct:pkg-bind 'fred
       (eval (read-from-string ...))))
or
   (when (find-package 'fred)
     (sct:pkg-bind 'fred
       (eval (read ...))))  ;; Which is equivalent to LOAD, sort of

That is, PKG-BIND (or any other method for binding the value of *PACKAGE*)
only affects the results of READing.

Below is a hack which you can patch into your environment to support the
following minor addition to #+/#- technology:

  (#+(package-present hubris) hubris:run-the-world
   #-(package-present hubris) ignore)

This turns into (HUBRIS:RUN-THE-WORLD) or (IGNORE) depending on whether the
HUBRIS package is present at read time.  This suffers from exactly the same
problem that KMP described for traditional #+/#- conditionalization: it
happens at READ time, which means that if you subsequently load the HUBRIS
package into your environment, you have to READ the forms again.

Of course, it would be wonderful to be able to do this portably, but as you
can see, under Genera (and, I assume, other lisp implementations) you have
to reach into the guts of the reader to get away with this kind of nonsense.

;;; From SYS:IO;READ.LISP.567 (Genera 7.2); I assume this will continue to
;;; work in later versions of Genera.
si::
(DEFUN XR-FEATURE-PRESENT (FEATURE)
  (COND ((ATOM FEATURE)
	 (OR (MEMBER FEATURE STATUS-FEATURE-LIST)
	     (PROG1 NIL				;make it obvious this is for effect
		    (UNLESS (MEMBER FEATURE *FEATURES-SEEN-BUT-NOT-PRESENT*)
		      (PUSH FEATURE *FEATURES-SEEN-BUT-NOT-PRESENT*)))))		      
	((EQ (CAR FEATURE) ':NOT)
	 (NOT (XR-FEATURE-PRESENT (CADR FEATURE))))
	((EQ (CAR FEATURE) ':AND)
	 (EVERY (CDR FEATURE) #'XR-FEATURE-PRESENT))
	((EQ (CAR FEATURE) ':OR)
	 (SOME (CDR FEATURE) #'XR-FEATURE-PRESENT))
	((member (car feature) '(:package-present :packages-present))
	 (every (cdr feature) #'cl:find-package))
	(*READ-SUPPRESS* NIL)
	(T (READ-ERROR NIL "Unknown form in #+ or #- feature list -- ~S" FEATURE))))