From: Jimka
Subject: reading into a package
Date: 
Message-ID: <1122749198.941358.222960@z14g2000cwz.googlegroups.com>
The Hyperspec says simply that the read function is effected
by the *package* variable but does not really explain how.
I assume that this means that all symbols encountered in the
file are interned into *package*.  Is this correct?

Is there a standard way for me to tell read which package
I want symbols interned into?

I've written a macro which sets the value of *package* to
my target package before calling READ and sets it back afterward.
But perhaps there is a better or more standard way for this?

Any advice?

-jim

From: Coby Beck
Subject: Re: reading into a package
Date: 
Message-ID: <CkQGe.149432$HI.144497@edtnps84>
"Jimka" <·····@rdrop.com> wrote in message 
·····························@z14g2000cwz.googlegroups.com...
> The Hyperspec says simply that the read function is effected
> by the *package* variable but does not really explain how.
> I assume that this means that all symbols encountered in the
> file are interned into *package*.  Is this correct?
>
> Is there a standard way for me to tell read which package
> I want symbols interned into?

(in-package "MY-PACKAGE")

> I've written a macro which sets the value of *package* to
> my target package before calling READ and sets it back afterward.
> But perhaps there is a better or more standard way for this?

Sounds reasonable if you are explicitly calling READ.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Peter Seibel
Subject: Re: reading into a package
Date: 
Message-ID: <m2d5p05950.fsf@gigamonkeys.com>
"Coby Beck" <·····@mercury.bc.ca> writes:

> "Jimka" <·····@rdrop.com> wrote in message 
> ·····························@z14g2000cwz.googlegroups.com...
>> The Hyperspec says simply that the read function is effected by the
>> *package* variable but does not really explain how.  I assume that
>> this means that all symbols encountered in the file are interned
>> into *package*.  Is this correct?
>>
>> Is there a standard way for me to tell read which package
>> I want symbols interned into?
>
> (in-package "MY-PACKAGE")
>
>> I've written a macro which sets the value of *package* to my target
>> package before calling READ and sets it back afterward.  But
>> perhaps there is a better or more standard way for this?
>
> Sounds reasonable if you are explicitly calling READ.

Though you'll probably want to use LET to bind *PACKAGE* rather than
setting it and setting it back. E.g.

  (let ((*package* (find-package :whatever)))
    (stuff-that-calls-read))

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Jimka
Subject: Re: reading into a package
Date: 
Message-ID: <1122761794.516037.276280@z14g2000cwz.googlegroups.com>
great, thanks for the info.
i'll try something like the following.

(defmacro read-in-package (package &rest body)
  `(let ((*package* (find-package ,package)))
      (read ,@body)))
From: Peter Seibel
Subject: Re: reading into a package
Date: 
Message-ID: <m264ur6gxl.fsf@gigamonkeys.com>
"Jimka" <·····@rdrop.com> writes:

> great, thanks for the info.
> i'll try something like the following.
>
> (defmacro read-in-package (package &rest body)
>   `(let ((*package* (find-package ,package)))
>       (read ,@body)))

That would work but is a bit silly since BODY would then have to
contain forms that would evaluate to legal arguments to READ. If
that's what you really want you might as well write it as a function:

  (defun read-in-package (package &rest read-args)
    (let ((*package* (find-package package)))
      (apply #'read read-args)))

More likely what you meant was something like this:

  (defmacro with-package ((package) &body body)
    `(let ((*package* (find-package ,package)))
       ,@body))

which lets you say:

  (with-package (:foo)
    (read)
    (read-from-string some-string)
    (read some-stream))

Though then you have to decide whether the relatively small savings of
typing provided by the macro compared to just writing the LET form out
are really worth it. At any rate, I'm sure you'd have figured this out
as soon as you actually started trying to use your macro, but I just
thought I'd clarify for any lurkers out there.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Jimka
Subject: Re: reading into a package
Date: 
Message-ID: <1122765148.281325.194780@g47g2000cwa.googlegroups.com>
Thanks Peter, it is good advice but I think I only want a replacement
for the READ function where I specify where it should intern
the un-qualified symbols.  It seems to me that the READ function
ought to have an optional arguement specifying the package, but
with the macro it is easy enough to write.  And yes I will assume
that the caller has specified READ compatible arguments--it will be
used in place of READ itself so that should be no problem.
From: Peter Seibel
Subject: Re: reading into a package
Date: 
Message-ID: <m21x5f6f7q.fsf@gigamonkeys.com>
"Jimka" <·····@rdrop.com> writes:

> Thanks Peter, it is good advice but I think I only want a replacement
> for the READ function where I specify where it should intern
> the un-qualified symbols.  It seems to me that the READ function
> ought to have an optional arguement specifying the package, but
> with the macro it is easy enough to write.  And yes I will assume
> that the caller has specified READ compatible arguments--it will be
> used in place of READ itself so that should be no problem.

Then you should really probably define read-in-package as a function,
something like what I showed in my previous post. There's no reason to
make it a macro.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Coby Beck
Subject: Re: reading into a package
Date: 
Message-ID: <Gf8He.172834$tt5.111255@edtnps90>
"Peter Seibel" <·····@gigamonkeys.com> wrote in message 
···················@gigamonkeys.com...
> "Jimka" <·····@rdrop.com> writes:
>
>> Thanks Peter, it is good advice but I think I only want a replacement
>> for the READ function where I specify where it should intern
>> the un-qualified symbols.  It seems to me that the READ function
>> ought to have an optional arguement specifying the package, but
>> with the macro it is easy enough to write.  And yes I will assume
>> that the caller has specified READ compatible arguments--it will be
>> used in place of READ itself so that should be no problem.
>
> Then you should really probably define read-in-package as a function,
> something like what I showed in my previous post. There's no reason to
> make it a macro.

I strongly second this.  It is not a macro you are writing, it is a 
function.  I you write this as a macro you merely get all the disadvantages 
of a macro with none of the benefits.  So I would go further and say there 
are good reasons to *not* make it a macro.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Pascal Bourguignon
Subject: Re: reading into a package
Date: 
Message-ID: <87vf2rb4ob.fsf@thalassa.informatimago.com>
"Jimka" <·····@rdrop.com> writes:
> Thanks Peter, it is good advice but I think I only want a replacement
> for the READ function where I specify where it should intern
> the un-qualified symbols.  It seems to me that the READ function
> ought to have an optional arguement specifying the package, but
> with the macro it is easy enough to write.  And yes I will assume
> that the caller has specified READ compatible arguments--it will be
> used in place of READ itself so that should be no problem.

How often do you use WRITE with all it's arguments instead of the
various PRIN[1CT] functions?

   write object &key array base case circle escape gensym length level
   lines miser-width pprint-dispatch pretty radix readably right-margin
   stream


But if you like this style, which is not exactly in the spirit of
Common Lisp which uses a number of special variables (too many some
say) to pass globally some common parameters, you can aways write:


(defpackage "MY-OWN-COMMON-LISP"
  (:nicknames "MY-OWN-CL")
  (:use "COMMON-LISP")
  (:shadow "READ"))

(in-package  "MY-OWN-COMMON-LISP")

(defun list-external-symbols (package &key (sorted t))
  (let ((pack (find-package package)))
    (if pack
      (let ((sl '())) (do-external-symbols (s pack) (push s sl))
           (if sorted (sort sl (function string<)) sl))
      (error "No package ~S" package))))


(let ((symbols (set-difference 
                  (list-external-symbols "COMMON-LISP" :sorted nil)
                  '(CL:READ))))
    (export symbols "MY-OWN-COMMON-LISP"))


(defun read (input-stream eof-error-p eof-value recursive-p 
             &key table base default-float-format eval suppress package)
  ;; TODO: some error checking: all arguments are mandatory!
  (let ((*READTABLE* table)
        (*READ-BASE* base)
        (*READ-DEFAULT-FLOAT-FORMAT* default-float-format)
        (*READ-EVAL* eval)
        (*READ-SUPPRESS* suppress)
        (*PACKAGE* (find-package package)))
     (cl:read input-stream eof-error-p eof-value recursive-p)))
(export 'read)


(defpackage "MY-OWN-COMMON-LISP-USER"
  (:nicknames "MY-OWN-CL-USER")
  (:use "MY-OWN-COMMON-LISP"))
(in-package  "MY-OWN-COMMON-LISP-USER")

(defpackage "INPUT-SYMBOLS" (:USE))

(read *standard-input* nil nil nil :table *readtable* :base 8
       :default-float-format 'single-float :eval nil :suppress nil
       :package "INPUT-SYMBOLS")

(10 hello 10.0)
--> (8 INPUT-SYMBOLS::HELLO 10.0)

Just mind using "MY-OWN-COMMON-LISP" instead of "COMMON-LISP" everywhere...


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s++:++ a+ C+++ UL++++ P--- L+++ E+++ W++ N+++ o-- K- w--- 
O- M++ V PS PE++ Y++ PGP t+ 5+ X++ R !tv b+++ DI++++ D++ 
G e+++ h+ r-- z? 
------END GEEK CODE BLOCK------
From: Edi Weitz
Subject: Re: reading into a package
Date: 
Message-ID: <uzms4m4wb.fsf@agharta.de>
On 30 Jul 2005 11:46:39 -0700, "Jimka" <·····@rdrop.com> wrote:

> I assume that this means that all symbols encountered in the file
> are interned into *package*.  Is this correct?

Yes, unless they are package-qualified.  So, if you file contains the
two lines

  foo
  bar::baz

then FOO will be interned into the current package while BAZ will be
interned into the BAR package.

> I've written a macro which sets the value of *package* to my target
> package before calling READ and sets it back afterward.  But perhaps
> there is a better or more standard way for this?

Your description seems to suggest that you do something like

  (let ((temp *package*))
    (setq *package* target-package)
    ;;; some code using READ
    (setq *package* temp))

If that's the case the more standard way of doing it would of course
be

  (let ((*package* target-package))
    ;;; some code using READ
    )

which is possible because *PACKAGE* is a special variable.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Thomas A. Russ
Subject: Re: reading into a package
Date: 
Message-ID: <ymi1x5dt6nr.fsf@sevak.isi.edu>
"Jimka" <·····@rdrop.com> writes:


> I've written a macro which sets the value of *package* to
> my target package before calling READ and sets it back afterward.
> But perhaps there is a better or more standard way for this?

Note that in Lisp you would normally not have to set it back
afterward if you use LET to bind the value.  For example:

(let ((*package* (find-package "MY-PACKAGE")))
   (read ...))

Of course it is important to check that the package you want really
exists, since setting *package* to NIL is a Bad Idea. :)

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