From: ·············@gmail.com
Subject: alists and packages question
Date: 
Message-ID: <d57499bd-1c35-4dd2-b2ff-3089ae98490b@56g2000hsm.googlegroups.com>
Hi,

I am trying to access elements of an alist from a "derived" package.
And I am succeeding, but in an ugly way.  What is the better way?
Here are the details.

I am defining an alist in one package, and I have a function to
retrieve its value.  I have exported that function.

(defpackage :atomic-processes
  (:use :cl :my-utils :physics-constants)
  (:export
...
   :rel-polarizability
   :polarizability))

(in-package :atomic-processes)
(defparameter *alpha-r*
  (list
   (cons 'H 4.5)
   (cons 'C 12.)
...
   (cons 'S-F6 30.))
  "Relative polarizabilities")

(defun rel-polarizability (id)
  (let ((res (cdr (assoc id
			 *alpha-r*))))
    (if (not res)
	(error "not found"))
	res)))

Now, I operate inside another package that uses :atomic-processes
Doing (rel-polarizability 'H) will return the error.  Instead I have
to do (rel-polarizability 'atomic-processes::h).

Is there some way around that?

I tried to build a new symbol as follows:
;; (defun rel-polarizability (id)
;;   (let* ((full-id (make-symbol
;; 		  (concatenate 'string
;; 			       "ATOMIC-PROCESSES::"
;; 			       (symbol-name id))))
;; 	 (res (cdr (assoc full-id
;; 			 *alpha-r*))))
;;     (if (not res)
;; 	(error (concatenate 'string (symbol-name full-id) " not found"))
;; 	res)))

but while it did build the symbol, it did not manage to return the
value.  Puzzled...

Thank you,

Mirko

From: Alberto Riva
Subject: Re: alists and packages question
Date: 
Message-ID: <g0cimm$ak48$1@usenet.osg.ufl.edu>
·············@gmail.com wrote:
> Hi,
> 
> I am trying to access elements of an alist from a "derived" package.
> And I am succeeding, but in an ugly way.  What is the better way?
> Here are the details.
> 
> I am defining an alist in one package, and I have a function to
> retrieve its value.  I have exported that function.
> 
> (defpackage :atomic-processes
>   (:use :cl :my-utils :physics-constants)
>   (:export
> ...
>    :rel-polarizability
>    :polarizability))
> 
> (in-package :atomic-processes)
> (defparameter *alpha-r*
>   (list
>    (cons 'H 4.5)
>    (cons 'C 12.)
> ...
>    (cons 'S-F6 30.))
>   "Relative polarizabilities")
> 
> (defun rel-polarizability (id)
>   (let ((res (cdr (assoc id
> 			 *alpha-r*))))
>     (if (not res)
> 	(error "not found"))
> 	res)))
> 
> Now, I operate inside another package that uses :atomic-processes
> Doing (rel-polarizability 'H) will return the error.  Instead I have
> to do (rel-polarizability 'atomic-processes::h).
> 
> Is there some way around that?

Yes, several:

a) EXPORT the symbols that you use in the alist (H, C, etc) from the 
:atomic-processes package;

b) Use :test #'string= in your assoc;

c) Use keywords instead of plain symbols: :H, :C, etc.

> 
> I tried to build a new symbol as follows:
> ;; (defun rel-polarizability (id)
> ;;   (let* ((full-id (make-symbol
> ;; 		  (concatenate 'string
> ;; 			       "ATOMIC-PROCESSES::"
> ;; 			       (symbol-name id))))
> ;; 	 (res (cdr (assoc full-id
> ;; 			 *alpha-r*))))
> ;;     (if (not res)
> ;; 	(error (concatenate 'string (symbol-name full-id) " not found"))
> ;; 	res)))
> 
> but while it did build the symbol, it did not manage to return the
> value.  Puzzled...

MAKE-SYMBOL creates an uninterned symbol, ie one that does not belong to 
any package. What you want is INTERN:

   (intern (symbol-name id) :atomic-processes)

Also, this is just a matter of style, but the last IF in your function 
could be rewritten as:

   (or res (error "~a not found" full-id))


Alberto
From: ·············@gmail.com
Subject: Re: alists and packages question
Date: 
Message-ID: <5796c8a6-8fa8-4ebf-82c2-bd9884d282cd@w7g2000hsa.googlegroups.com>
On May 13, 1:21 pm, Alberto Riva <·····@nospam.ufl.edu> wrote:
> ·············@gmail.com wrote:
> > Hi,
>
> > I am trying to access elements of an alist from a "derived" package.
> > And I am succeeding, but in an ugly way.  What is the better way?
> > Here are the details.
>
> > I am defining an alist in one package, and I have a function to
> > retrieve its value.  I have exported that function.
>
> > (defpackage :atomic-processes
> >   (:use :cl :my-utils :physics-constants)
> >   (:export
> > ...
> >    :rel-polarizability
> >    :polarizability))
>
> > (in-package :atomic-processes)
> > (defparameter *alpha-r*
> >   (list
> >    (cons 'H 4.5)
> >    (cons 'C 12.)
> > ...
> >    (cons 'S-F6 30.))
> >   "Relative polarizabilities")
>
> > (defun rel-polarizability (id)
> >   (let ((res (cdr (assoc id
> >                     *alpha-r*))))
> >     (if (not res)
> >    (error "not found"))
> >    res)))
>
> > Now, I operate inside another package that uses :atomic-processes
> > Doing (rel-polarizability 'H) will return the error.  Instead I have
> > to do (rel-polarizability 'atomic-processes::h).
>
> > Is there some way around that?
>
> Yes, several:
>
> a) EXPORT the symbols that you use in the alist (H, C, etc) from the
> :atomic-processes package;
>
> b) Use :test #'string= in your assoc;
>
> c) Use keywords instead of plain symbols: :H, :C, etc.
>

I'll try keywords.  Thanks.
>
>
> > I tried to build a new symbol as follows:
> > ;; (defun rel-polarizability (id)
> > ;;   (let* ((full-id (make-symbol
> > ;;                   (concatenate 'string
> > ;;                                "ATOMIC-PROCESSES::"
> > ;;                                (symbol-name id))))
> > ;;          (res (cdr (assoc full-id
> > ;;                          *alpha-r*))))
> > ;;     (if (not res)
> > ;;         (error (concatenate 'string (symbol-name full-id) " not found"))
> > ;;         res)))
>
> > but while it did build the symbol, it did not manage to return the
> > value.  Puzzled...
>
> MAKE-SYMBOL creates an uninterned symbol, ie one that does not belong to
> any package. What you want is INTERN:
>
>    (intern (symbol-name id) :atomic-processes)
thank you, again.

> Also, this is just a matter of style, but the last IF in your function
> could be rewritten as:
>
>    (or res (error "~a not found" full-id))

THANK YOU !!!!!!!!!!!!!!!!!

um, sorry for shouting.  I've been coding that ugly if construct and I
was sure there was a better way.  Thank you again.
>
> Alberto

Mirko
From: Thomas A. Russ
Subject: Re: alists and packages question
Date: 
Message-ID: <ymilk2dvlq8.fsf@blackcat.isi.edu>
·············@gmail.com writes:

> Hi,
> 
> I am trying to access elements of an alist from a "derived" package.
> And I am succeeding, but in an ugly way.  What is the better way?
> Here are the details.
> 
> I am defining an alist in one package, and I have a function to
> retrieve its value.  I have exported that function.
> 
> (defpackage :atomic-processes
>   (:use :cl :my-utils :physics-constants)
>   (:export
> ...
>    :rel-polarizability
>    :polarizability))
> 
> (in-package :atomic-processes)
> (defparameter *alpha-r*
>   (list
>    (cons 'H 4.5)
>    (cons 'C 12.)
> ...
>    (cons 'S-F6 30.))
>   "Relative polarizabilities")

OK.  The keys in this table are all interned in the ATOMIC-PROCESSES
package.  Those are the symbols you will have to use.

> (defun rel-polarizability (id)
>   (let ((res (cdr (assoc id
> 			 *alpha-r*))))
>     (if (not res)
> 	(error "not found"))
> 	res)))

Off topic, but a more robust implementation would test the return value
of ASSOC for the error.  That would allow you to have a NIL value as a
legitimate value in your table (even if you actually don't have such
values), but that would make your lookup function a more general
utility:

(defun eassoc (key alist)
  (let ((res (assoc key alist)))
    (if res
        (cdr res)
        (error "Key ~A not found." key))))


> Now, I operate inside another package that uses :atomic-processes
> Doing (rel-polarizability 'H) will return the error.  Instead I have
> to do (rel-polarizability 'atomic-processes::h).

Correct.  Because the symbol H in your other package is not the same as
the symbol H in the ATOMIC-PROCESSES package.  You have to use the same
symbol.

> Is there some way around that?

There are a couple of choices:
 1) Use qualified names for the keys, like you are doing above.
 2) Make the qualified names a bit nicer by EXPORTing the key symbols
    from the ATOMIC-PROCESSES package and give the package a short
    nickname, perhaps "AP".  Then you would specify
       (rel-polarizability 'ap:h)
 3) Actually, since you seem to be USEing the ATOMIC-PROCESSES package
    already (because the function name rel-polarizability doesn't need a
    package qualifier, just exporting the key symbols would remove the
    need to use qualified names.
 4) Use keywords instead of your own symbols.  Probably not the best
    choice for the current application, as a style issue.
 5) Use a different test in ASSOC besides the default EQL.  For your
    purposes, with symbols as keys, STRING= should work.  Consider the
    following examples:

      (assoc 'foo '((:foo t) (bar nil) (foo yuck)))  
      ==> (FOO YUCK)

      (assoc 'foo '((:foo t) (bar nil) (foo yuck)) :test #'string=)
      ==> (:FOO T)

> I tried to build a new symbol as follows:
> ;; (defun rel-polarizability (id)
> ;;   (let* ((full-id (make-symbol
> ;; 		  (concatenate 'string
> ;; 			       "ATOMIC-PROCESSES::"
> ;; 			       (symbol-name id))))
> ;; 	 (res (cdr (assoc full-id
> ;; 			 *alpha-r*))))
> ;;     (if (not res)
> ;; 	(error (concatenate 'string (symbol-name full-id) " not found"))
> ;; 	res)))
> 
> but while it did build the symbol, it did not manage to return the
> value.  Puzzled...

It did not build the symbol you expected it to build.  You need to look
up INTERN and understand what interning and lookup of symbol names
does.  As a start, look at the output of the following and see if that
helps:

   'atomic-processes::h

   (make-symbol "ATOMIC-PROCESSES::H")

   (symbol-name 'atomic-processes::h)

   (symbol-package 'atomic-processes::h)

   (symbol-name (make-symbol "ATOMIC-PROCESSES::H"))

   (symbol-package (make-symbol "ATOMIC-PROCESSES::H"))

> 
> Thank you,
> 
> Mirko

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: David Golden
Subject: Re: alists and packages question
Date: 
Message-ID: <fCkWj.25431$j7.469402@news.indigo.ie>
·············@gmail.com wrote:

> Hi,
> 
> I am trying to access elements of an alist from a "derived" package.
> And I am succeeding, but in an ugly way.  What is the better way?
> Here are the details.
> 
> I am defining an alist in one package, and I have a function to
> retrieve its value.

Just to note, alists aren't "in" packages. Symbols are "in" packages.

You might define an alist "while 'you' are in" a package
["in-package"...], which means the lisp reader is interpreting
un-package-qualified symbols you enter as being "in" a particular
package. Thus, you might bind a symbol in that package to the alist
you are defining, and you might put in the alist keys and values that
are symbols in that package. But thinking of the /alist itself/ as
being "in" the package will lead straight to confusion. 

Just remember symbols themselves are the things that are in packages. 

Your puzzlement probably ultimately stems from a common misconception
about packages for people coming from other languages with what are
sometimes called module systems (though that term is itself rather
overloaded).

Common Lisp packages are actually very simple things, pretty much just
bunches of symbols (remember that symbols themselves, as a core feature
of lisp, are first-class objects in lisp, so it makes some sense to
support having named collections of 'em).  It's just important to bear
that in mind when dealing with packages - they contain names i.e.
symbols, not bindings. "The package system is not a module system".   

The quick answer you want, but which mightn't lead to full understanding
might be just "use keywords for the keys".

> I have exported that function. 
> 
> (defpackage :atomic-processes
>   (:use :cl :my-utils :physics-constants)
>   (:export
> ...
>    :rel-polarizability
>    :polarizability))
> 
> (in-package :atomic-processes)

^^ So, you're in that package.

> (defparameter *alpha-r*
>   (list
>    (cons 'H 4.5)
>    (cons 'C 12.)
>

^^ so, therefore, the unqualified H and C symbols you are associating
are in the atomic-processes package!  You could just use :H and :C
(keywords) instead of 'H and 'C  - lisp has a special keyword package
with special syntax.  or import H and C from the atomic-processes
package into packages you want to use them from when you're in, but
keywords, like the name suggests, work really well for keys :-)
 
> Now, I operate inside another package that uses :atomic-processes
> Doing (rel-polarizability 'H) will return the error.  Instead I have
> to do (rel-polarizability 'atomic-processes::h).
> 

^^^ because the symbol with symbol-name "h" you associated the value
with was in the "atomic-processes" package[-of-symbols] ! This is
entirely expected.

> Is there some way around that?
> 
yes.

> I tried to build a new symbol as follows:

> (make-symbol (concatenate 'string "ATOMIC-PROCESSES::"
>                              (symbol-name id))))


That's not doing what you probably think it does.  That's making an
uninterned symbol #:|ATOMIC-PROCESSES::H| 

- i.e. a symbol whose /symbol-name itself/ starts with some characters
that happen to look like the usual lisp syntax for a package prefix.
 
(intern "H" (find-package "ATOMIC-PROCESSES")) straightforwardly enough
returns a symbol with symbol-name h in package with package name
atomic-processes, but I hope you see you probably don't actually want
or need that here.
From: ·············@gmail.com
Subject: Re: alists and packages question
Date: 
Message-ID: <61307e19-460c-4d5d-a6e8-2f094398d031@t54g2000hsg.googlegroups.com>
On May 13, 1:55 pm, David Golden <············@oceanfree.net> wrote:
> ·············@gmail.com wrote:
> > Hi,
>
> > I am trying to access elements of an alist from a "derived" package.
> > And I am succeeding, but in an ugly way.  What is the better way?
> > Here are the details.
>
> > I am defining an alist in one package, and I have a function to
> > retrieve its value.
>
> Just to note, alists aren't "in" packages. Symbols are "in" packages.
>
> You might define an alist "while 'you' are in" a package
> ["in-package"...], which means the lisp reader is interpreting
> un-package-qualified symbols you enter as being "in" a particular
> package. Thus, you might bind a symbol in that package to the alist
> you are defining, and you might put in the alist keys and values that
> are symbols in that package. But thinking of the /alist itself/ as
> being "in" the package will lead straight to confusion.
>
> Just remember symbols themselves are the things that are in packages.

Quite right.  I played a bit with trying atomic-processes::alist, but
that got me nowhere, and when I actually "printed it out" I saw the
symbols being in the package.  But thanks for nicely explaining what I
was seeing.

>
> Your puzzlement probably ultimately stems from a common misconception
> about packages for people coming from other languages with what are
> sometimes called module systems (though that term is itself rather
> overloaded).

No.  my puzzlement stems from my age, and the slowness (or lack
thereof) of my neural connections.  Maybe I should just switch to
basic(s) :-)

>
> Common Lisp packages are actually very simple things, pretty much just
> bunches of symbols (remember that symbols themselves, as a core feature
> of lisp, are first-class objects in lisp, so it makes some sense to
> support having named collections of 'em).  It's just important to bear
> that in mind when dealing with packages - they contain names i.e.
> symbols, not bindings. "The package system is not a module system".
>
> The quick answer you want, but which mightn't lead to full understanding
> might be just "use keywords for the keys".
>
> > I have exported that function.
>
> > (defpackage :atomic-processes
> >   (:use :cl :my-utils :physics-constants)
> >   (:export
> > ...
> >    :rel-polarizability
> >    :polarizability))
>
> > (in-package :atomic-processes)
>
> ^^ So, you're in that package.
>
> > (defparameter *alpha-r*
> >   (list
> >    (cons 'H 4.5)
> >    (cons 'C 12.)
>
> ^^ so, therefore, the unqualified H and C symbols you are associating
> are in the atomic-processes package!  You could just use :H and :C
> (keywords) instead of 'H and 'C  - lisp has a special keyword package
> with special syntax.  or import H and C from the atomic-processes
> package into packages you want to use them from when you're in, but
> keywords, like the name suggests, work really well for keys :-)
>
> > Now, I operate inside another package that uses :atomic-processes
> > Doing (rel-polarizability 'H) will return the error.  Instead I have
> > to do (rel-polarizability 'atomic-processes::h).
>
> ^^^ because the symbol with symbol-name "h" you associated the value
> with was in the "atomic-processes" package[-of-symbols] ! This is
> entirely expected.
>
> > Is there some way around that?
>
> yes.
>
> > I tried to build a new symbol as follows:
> > (make-symbol (concatenate 'string "ATOMIC-PROCESSES::"
> >                              (symbol-name id))))
>
> That's not doing what you probably think it does.  That's making an
> uninterned symbol #:|ATOMIC-PROCESSES::H|
>
> - i.e. a symbol whose /symbol-name itself/ starts with some characters
> that happen to look like the usual lisp syntax for a package prefix.
>
> (intern "H" (find-package "ATOMIC-PROCESSES")) straightforwardly enough
> returns a symbol with symbol-name h in package with package name
> atomic-processes, but I hope you see you probably don't actually want
> or need that here.

I went with the keyword suggestion.  Works as advertised.  Thanks.