Pascal Costanza <firstname.lastname@example.org> wrote:
| Or, again, use any of those deflex or defglobal macros,
| which give you global lexicals. Here is a rough sketch:
| (defmacro defglobal (name value)
| (let ((var (copy-symbol name)))
| (defvar ,var ,value)
| (define-symbol-macro ,name ,var)
| Untested, but should work.
It does, but I (slightly) prefer my version of DEFLEX
because it doesn't leave uninterned symbols dangling about,
the backing symbol is in the same package as the symbol macro,
and like other DEFxxx forms it returns the symbol being defined:
> (defglobal foo 13)
> (deflex bar 47)
> (describe 'foo)
FOO is an internal symbol in the COMMON-LISP-USER package.
It is a symbol macro with expansion: #:FOO.
> (describe 'bar)
BAR is an internal symbol in the COMMON-LISP-USER package.
It is a symbol macro with expansion: *STORAGE-FOR-DEFLEX-VAR-BAR*.
But as a tutorial proof of concept, your DEFGLOBAL seems fine.
 My current version:
(defmacro deflex (var val &optional (doc nil docp))
"Define a top level (global) lexical VAR with initial value VAL,
which is assigned unconditionally as with DEFPARAMETER. If a DOC
string is provided, it is attached to both the name |VAR| and the
name *STORAGE-FOR-DEFLEX-VAR-|VAR|* as a documentation string of
kind 'VARIABLE. The new VAR will have lexical scope and thus may be
shadowed by LET bindings without affecting its dynamic (global) value."
(let* ((s0 (symbol-name '#:*storage-for-deflex-var-))
(s1 (symbol-name var))
(s2 (symbol-name '#:*))
(s3 (symbol-package var))
(backing-var (intern (concatenate 'string s0 s1 s2) s3)))
;; Note: The DEFINE-SYMBOL-MACRO must be the last thing we do so
;; that the value of the form is the symbol VAR.
(defparameter ,backing-var ,val ,doc)
(setf (documentation ',var 'variable) ,doc)
(define-symbol-macro ,var ,backing-var))
(defparameter ,backing-var ,val)
(define-symbol-macro ,var ,backing-var)))))
Rob Warnock <email@example.com>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607