Eli Bendersky <eliben@gmail.com> wrote:
+---------------
| > [1] My current version:
| >
| > (defmacro deflex (var val &optional (doc nil docp))
...[trimmed]...
|
| Rob, this looks interesting. Can I consider it as a viable replacement
| for defparameter at the top level for defining lexical globals ?
+---------------
I certainly use it that way quite liberally in my own code,
especially for variables that are going to be set or referenced
at the REPL.
But I also still use DEFPARAMETER (with traditional *earmuffs*
on the variable) for variables that are ever going to be dynamically
rebound, since DEFLEX is *NOT* compatible with the DEFVAR/SHADOWABLE
approach[1] mentioned elsewhere in this thread. That is, if you do
(DEFVAR/SHADOWABLE FOO 13) or (DEFINE-SYMBOL-MACRO FOO (SYMBOL-VALUE 'FOO)),
then you can both LET-bind FOO lexically *and* reference the global
value using (LOCALLY (DECLARE (SPECIAL FOO)) FOO), e.g.:
> (defvar/shadowable foo 13)
FOO
> (defun foo () foo)
FOO
> (let ((foo 27))
(locally (declare (special foo)) (setf foo 53))
(list foo (foo) (locally (declare (special foo)) foo)))
(27 53 53)
> foo
53
> (locally (declare (special foo)) foo)
53
>
But if you (DEFLEX FOO 13), then (LOCALLY (DECLARE (SPECIAL FOO)) FOO)
is going to get the value cell for the symbol FOO itself, *not*
the global value of the backing variable for FOO. This can lead
to considerable confusion:
> (deflex foo 13)
FOO
> (defun foo () foo)
FOO
> (let ((foo 27))
(locally (declare (special foo)) (setf foo 53))
(list foo (foo) (locally (declare (special foo)) foo)))
(27 13 53)
> foo
13
> (locally (declare (special foo)) foo)
53
>
+---------------
| Is it portable across all implementation ?
+---------------
As far as I know, yes, it should be. It uses only ANSI CL constructs.
However, be aware that in CMUCL-19d and earlier there was a bug
in macro expansion that in some cases [e.g., "INCF FOO", but not
just "FOO" or "SETF FOO"] caused references to symbol macros that
had been shadowed by lexical variables to expand to the symbol macro
expansion instead of refering to the lexical variable. [This would
affect all symbol macros, including both DEFLEX and DEFVAR/SHADOWABLE.]
This bug was fixed in the CVS for "code/eval.lisp" as of Revision
1.43 2006-12-19, but to my knowledge there is not yet an official
"cmucl-19d-patch-NNN" for this. I posted a patch here in article
<URL:news:Y_Cdnbvi_4Ir4RvYnZ2dnUVZ_tunnZ2d@speakeasy.net> on 2006-12-18
[which also works in CMUCL-19c], or you can just extract the
routine MACROEXPAND-1 from the CVS tree version of "eval.lisp" at
<http://common-lisp.net/cgi-bin/viewcvs.cgi/*checkout*/src/
code/eval.lisp?rev=1.43&root=cmucl>.
-Rob
[1] In case you missed it, I was proposing this if one wanted
to use the "shadowable global special" approach:
(defmacro defvar/shadowable (var &optional value (doc nil docp))
`(progn
(setf (symbol-value ',var) ,value)
,@(when docp
(list `(setf (documentation ',var 'variable) ,doc)))
(define-symbol-macro ,var (symbol-value ',var))))
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607