From: Frode Vatvedt Fjeld
Subject: Finding a symbol's accessibility
Date: 
Message-ID: <2helm5st5d.fsf@dslab7.cs.uit.no>
If I have a symbol and its (symbol-package symbol), is there a better
way to find the symbol's status than to take the secondary value of
(find-symbol (symbol-name symbol) (symbol-package symbol))?

-- 
Frode Vatvedt Fjeld

From: Kent M Pitman
Subject: Re: Finding a symbol's accessibility
Date: 
Message-ID: <sfwofl9oi0y.fsf@shell01.TheWorld.com>
Frode Vatvedt Fjeld <······@acm.org> writes:

> If I have a symbol and its (symbol-package symbol), is there a better
> way to find the symbol's status than to take the secondary value of
> (find-symbol (symbol-name symbol) (symbol-package symbol))?

Well, if you already have symbol in some variable symbol and 
(symbol-package symbol) in some variable symbol-package, then just
 (find-symbol (symbol-name symbol) symbol-package)
should help--no need to call symbol-package again.  ;)

But the real answer to your question is that what you have done is buggy,
so this is a trick question.

A symbol's package does NOT tell you that the symbol is even in that package.
Nor that it is only in the package.  So, first, "the symbol's status" is
a meaningless expression in English.  You mean "the symbol's status in a
given package".   There are precious few things you can learn from knowing
the symbol and its package (other than how to print it, which is heuristic
only), because the package is not reliable.

What you really want is something like the following:

 (defun package-symbol-status (symbol &optional (package *package*))
   (multiple-value-bind (packaged-symbol packaged-symbol-status)
       (find-symbol (symbol-name symbol) package)
     (cond ((and packaged-symbol-status (eq packaged-symbol symbol))
	    packaged-symbol-status)
           (t
            nil))))

or just

 (defun package-symbol-status (symbol &optional (package *package*))
   (multiple-value-bind (packaged-symbol packaged-symbol-status)
       (find-symbol (symbol-name symbol) package)
     (cond ((eq packaged-symbol symbol)
	    packaged-symbol-status)
           (t
            nil))))

Some people prefer to write the latter because they think it's "cleaner" in one
obscure case, but I'm pretty sure the result is the same, since the weird
case where packaged-symbol-status is NIL but (eq packaged-symbol symbol)
is T would be the case of NIL, NIL coming back.  That would be a case where
you are testing for NIL in a package containing no NIL (e.g., a package 
that used no other packages, and especially not CL).  In that case,  
the primary value would be the boolean NIL, not the symbol NIL, even though
those are EQ, but even though it would enter the wrong clause, it would
do so only when packaged-symbol-status was NIL anyway, so it doesn't matter
which clause you enter.

But your question is phrased in a way that suggests you're going to do
 (package-symbol-status symbol (symbol-package symbol))
and my belief is that there is no meaningful computation you can do on the
result of that other than print (or an equivalent, such as make-load-form
or some sort of serialization).  In most cases, the real usefulness of
knowing the status is to do
 (package-symbol-status symbol some-other-package)
which acts as a kind of boolean value to determine whether the symbol is
an external of SOME-OTHER-PACKAGE.  This might be useful in documentation,
e.g., to tell if a symbol is accessible to the user.  In such case, the symbol
should perhaps be displayed not as (prin1 foo), which would show its home
package, in which it might not even be an external in some obscure cases, or
which could even be NIL, showing it as a gensym in really obscure cases,
but rather as (let ((*package* some-other-package)) (prin1 symbol)) so as
to emphasize its having been exported in the package you care about.
From: Frode Vatvedt Fjeld
Subject: Re: Finding a symbol's accessibility
Date: 
Message-ID: <2h4rn1sp1n.fsf@dslab7.cs.uit.no>
Kent M Pitman <······@world.std.com> writes:

> But your question is phrased in a way that suggests you're going to
> do (package-symbol-status symbol (symbol-package symbol)) and my
> belief is that there is no meaningful computation you can do on the
> result of that other than print (or an equivalent, such as
> make-load-form or some sort of serialization).>

Thanks for your thorough reply. What I'm doing is writing a symbol
completion function that given a string (for example "do-", "cl:do-"
or "cl::do-") will figure out the correct list of matching symbols
that exists in the appropriate packages.

-- 
Frode Vatvedt Fjeld
From: James A. Crippen
Subject: Re: Finding a symbol's accessibility
Date: 
Message-ID: <m3k7vma2gw.fsf@kappa.unlambda.com>
Frode Vatvedt Fjeld <······@acm.org> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > But your question is phrased in a way that suggests you're going to
> > do (package-symbol-status symbol (symbol-package symbol)) and my
> > belief is that there is no meaningful computation you can do on the
> > result of that other than print (or an equivalent, such as
> > make-load-form or some sort of serialization).>
> 
> Thanks for your thorough reply. What I'm doing is writing a symbol
> completion function that given a string (for example "do-", "cl:do-"
> or "cl::do-") will figure out the correct list of matching symbols
> that exists in the appropriate packages.

Sounds useful.  Please post it to the group when you're done, if
possible.

'james

-- 
James A. Crippen <·····@unlambda.com> ,-./-.  Anchorage, Alaska,
Lambda Unlimited: Recursion 'R' Us   |  |/  | USA, 61.20939N, -149.767W
Y = \f.(\x.f(xx)) (\x.f(xx))         |  |\  | Earth, Sol System,
Y(F) = F(Y(F))                        \_,-_/  Milky Way.