From: Michael Hönisch
Subject: Packages and conditions
Date: 
Message-ID: <4181198c$1@news.adm.arcor.net>
Hello,

The following statements create a package named pack, define the package 
  pack as the actual package and assign the variable foo (in the package 
pack) the value 1000. The beaviour seems clear.

(make-package :pack)
(in-package :pack)
(setq foo 1000)


But the folliwing I don't undestand:

/-- begin ---/

[1]> (pprint *package*)

#<PACKAGE COMMON-LISP-USER>

[2]> (unless (find-package :foo) (progn (make-package :foo) (in-package 
:foo) (setq bar 100)))
100
FOO[3]> (pprint *package*)

#<PACKAGE FOO>

FOO[4]> (pprint COMMON-LISP-USER::bar)

100

FOO[5]> (pprint foo::bar)

*** - EVAL: variable BAR has no value
The following restarts are available:
STORE-VALUE    :R1      You may input a new value for BAR.
USE-VALUE      :R2      You may input a value to be used instead of BAR.

Break 1 FOO[6]>

/-- end ---/


The new created variable "bar" is in the package COMMON-LISP-USER, which 
was active before the condition.

Why ist the variable bar not in the package :foo? Is it possible to 
create a package in the body of a condition and to define that package 
as the actual package and place a global variable inside that new package?


Regards
Michael

From: Marco Antoniotti
Subject: Re: Packages and conditions
Date: 
Message-ID: <v_cgd.21$TY6.13486@typhoon.nyu.edu>
Hi

The problem you have is explained by looking at what gets READ in at 
which time and what gets evaluated at which time.


Michael H�nisch wrote:
> Hello,
> 
> The following statements create a package named pack, define the package 
>  pack as the actual package and assign the variable foo (in the package 
> pack) the value 1000. The beaviour seems clear.
> 
> (make-package :pack)

Form read in package :cl-user (presumably) and evaluated.

> (in-package :pack)

Form read in package :cl-user and evaluated.  Now we are in package :pack.


> (setq foo 1000)

Form read in package :pack and evualuated.


> 
> 
> But the folliwing I don't undestand:
> 
> /-- begin ---/
> 
> [1]> (pprint *package*)
> 
> #<PACKAGE COMMON-LISP-USER>
> 
> [2]> (unless (find-package :foo) (progn (make-package :foo) (in-package 
> :foo) (setq bar 100)))
> 100

The whole form is read in package :cl-user (hence the symbol BAR resides 
there), and then evaluated.  Hence you set the symbol cl-user::bar to 
100 since the actual call to IN-PACKAGE happens after the symbol BAR has 
been read in.



> FOO[3]> (pprint *package*)
> 
> #<PACKAGE FOO>
> 
> FOO[4]> (pprint COMMON-LISP-USER::bar)
> 
> 100
> 
> FOO[5]> (pprint foo::bar)
> 
> *** - EVAL: variable BAR has no value
> The following restarts are available:
> STORE-VALUE    :R1      You may input a new value for BAR.
> USE-VALUE      :R2      You may input a value to be used instead of BAR.
> 
> Break 1 FOO[6]>
> 
> /-- end ---/
> 
> 
> The new created variable "bar" is in the package COMMON-LISP-USER, which 
> was active before the condition.
> 
> Why ist the variable bar not in the package :foo? Is it possible to 
> create a package in the body of a condition and to define that package 
> as the actual package and place a global variable inside that new package?

Yes, but you have to do it very carefully.

(progn
    (make-package :pack)
    (intern "BAR" :pack)
    (setf (symbol-value (find-symbol "BAR" :pack)) 100))

Cheers

--
marco
From: Alan Crowe
Subject: Re: Packages and conditions
Date: 
Message-ID: <864qked9e1.fsf@cawtech.freeserve.co.uk>
Michael.Hoenisch wrote:

     But the folliwing I don't undestand:

     /-- begin ---/

     [1]> (pprint *package*)

     #<PACKAGE COMMON-LISP-USER>

     [2]> (unless (find-package :foo) (progn (make-package :foo) (in-package 
     :foo) (setq bar 100)))
     100
     FOO[3]> (pprint *package*)

     #<PACKAGE FOO>

     FOO[4]> (pprint COMMON-LISP-USER::bar)

     100

     FOO[5]> (pprint foo::bar)

     *** - EVAL: variable BAR has no value
     The following restarts are available:

This is the Read-Eval-Print-Loop doing all its reading,
reading right to the end, before anything goes to the next
stage for evaluation.

Plan A - tell the reader to switch package before it gets to
BAR with the #. read macro

(progn #.(in-package "FOO") (prog1 'bar #.(in-package "CL-USER")))
=> FOO::BAR

I've not seen others do this. I assume ones code ends in a
tangled mess if one does down this path.

Michael ended with a question:
> Is it possible to create a package in the body of a
> condition and to define that package as the actual package
> and place a global variable inside that new package?

I think this solves the immediate problem

* (case (random 2)
    (0 (make-package "ALAN")(intern "DINNER" "ALAN"))
    (1 (make-package "CROWE")(intern "CHEESE" "CROWE")))

ALAN::DINNER
NIL
* (case (random 2)
    (0 (make-package "ALAN")(intern "DINNER" "ALAN"))
    (1 (make-package "CROWE")(intern "CHEESE" "CROWE")))

CROWE::CHEESE
NIL
* (case (random 2)
    (0 (make-package "ALAN")(intern "DINNER" "ALAN"))
    (1 (make-package "CROWE")(intern "CHEESE" "CROWE")))

Error in function MAKE-PACKAGE:  A package named "CROWE" already exists

Restarts:
  0: [CONTINUE] Leave existing package alone.
  1: [ABORT   ] Return to Top-Level.

However it is unusual to be creating packages at run
time. It would be more common to have some packages
available and use package qualifiers eg FOO::BAR

Presumably it is unusual to create packages at run time
precisely because that is too late for reading symbols into
the intended package, just as Michael has observed, but I'm
too hungry to think about this now.

Alan Crowe
Edinburgh
Scotland