Juho Snellman <jsnell@[EMAIL PROTECTED]
> writes:
> Chris Barts <chbarts+usenet@[EMAIL PROTECTED]
> writes:
> > > (defun pervasively-special-p (var)
> > > (values
> > > (ignore-errors ;in case binding a constant doesn't work
> > > (eval `(let ((,var nil))
> > > (declare (special ,var))
> > > (let ((,var t))
> > > (symbol-value ',var)))))))
> [...]
> > Except this fails on SBCL:
> >
> > {begin transcript:
> > CL-USER> (pervasively-special-p '*print-base*)
> [...]
> > OK, the warnings are expected by design (SBCL is a bit... chatty) but
> > shouldn't the value be T regardless? Is this a bug in SBCL? I'm
> > running SBCL 1.0.6.
>
> No, it's not an SBCL bug. The code is invoking at least two bits of
> undefined behaviour:
>
> * Declaring a symbol in CL special (11.1.2.1.2).
Yep, that's what it says. Still, not that it matters because it's just
my personal point of view, I always thought of that as forbidding you
from declaring system special that wasn't already special, that is, from
changing the behavior of a system-supplied symbol.
> * Binding the value of *print-base* to NIL and T, when it's defined
> by the spec to be a radix (1.4.4.22).
You're just no fun. :)
Ok, I'll give it another go. This should avoid a bunch of those details
everyone's nagging about.
(defun pervasively-special-p (var)
(check-type var symbol "a variable name")
(if (eq (symbol-package var) (load-time-value (find-package "CL")))
(and (boundp var)
(let* ((name (symbol-name var))
(n-chars (length name)))
(and (> n-chars 0)
(eql (char name 0) #\*)
(eql (char name (- n-chars 1)) #\*)
:so-it-would-seem)))
(values
(handler-bind ((warning #'(lambda (warning)
(when (find-restart 'muffle-warning
warning)
(muffle-warning warning)))))
(ignore-errors ;in case binding a constant doesn't work
(eval `(let ((,var nil))
(declare (special ,var))
(let ((,var t))
(symbol-value ',var)))))))))


|