Robert Maas <usenet2.3.CalRobert@SpamGourmet.Com> wrote:
+---------------
| Then suddenly I remembered DESCRIBE, which printed out among other things:
| It is a special variable; no current value.
| OK, so I should have thought of that first. But there's no SPECIALP
| predicate or anything else I can find. How does DESCRIBE know that
| the symbol is special? How does the JIT compiler built into the
| REP loop know that it's special when it's deciding whether to do
| lexical or special bindings?
...
| This is in CMUCL, if it makes any difference. I'm hoping for some
| ANSI-CL function (predicate) rather than a CMUCL-specific function
| (predicate), but I'm curious in any case.
+---------------
I could give you a CMUCL-specific answer, involving macroexpanding
(DEFVAR *FOO*) [*without* setting a value] and then poking around
in the CMUCL sources and eventually finding that you might want to
use the dreaded infamous CMUCL "INFO" database that DESCRIBE uses
internally [see the source at "~cmucl-19c/src/code/describe.lisp"]:
cmu> (info variable kind '*foo*)
:GLOBAL
NIL
cmu> (defvar *foo*)
*FOO*
cmu> (info variable kind '*foo*)
:SPECIAL
T
cmu>
[Other possible answers for INFO VARIABLE KIND are :CONSTANT
(for DEFCONSTANT), :MACRO (for symbol macros), and :ALIEN (for
the CMUCL's "alien" FFI data), so you'd want to be prepared
for all of those, too. Similar things are available for INFO
FUNCTION KIND, but I don't think you really want to go there.]
But that's really a red herring, sorry to bring it up... ;-} ;-}
If you're trying to be portable, probably the best thing you can do
is send the output of DESCRIBE to a string stream and then use a
simple per-implementation pattern match to pull the info you need
out of it. That's likely to be more stable than any weird internal
interfaces [such as CMUCL's INFO], and *much* easier to add support
for new implementations:
(defun globally-special-p (symbol)
(let ((description (with-output-to-string (s) (describe symbol s))))
#+cmu (search "It is a special variable" description)
#+clisp (search "variable declared SPECIAL" description)
;; Add more implementations here...
#-(or cmu clisp)
(error "Not supported in ~A" (lisp-implementation-type))))
This group could probably flesh that out for a dozen more
implementations in only a handful of followup posts... ;-} ;-}
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607