SDS <···········@cctrading.com> writes:
> In emacs lisp one can do
> (let ((float-output-format "%.5f"))
> (whatever))
> to set float-output-format temporary and reset it to the original value
> afterwards. The same form will not work in CL - because let will create
> a new binding. Nevertheless, it might be useful to set a global
> variable to something temporary. For a single variable, the following
> macro will probably do:
Is this what you had in mind?
USER(125): (defvar *glob* 10)
*GLOB*
USER(126): *glob*
10
USER(127): (defun foo ()
(format t "Foo:Glob = ~W~%" *glob*))
FOO
USER(128): (foo)
Foo:Glob = 10
NIL
USER(129): (defun bar ()
(let ((*glob* 42))
(declare (special *glob*))
(foo)))
BAR
USER(130): (bar)
Foo:Glob = 42
NIL
USER(131): (foo)
Foo:Glob = 10
NIL
USER(132):
All you need is to make sure that you are using special variables to
get the behavior that you wanted. In elisp variables are special by
default (do they even have lexical scope as a possibility?) while in
Common Lisp variable have lexical scope by default. IMHO lexical
scope is usually the Right Thing(tm) and should be the default, but I
can see the adaptation problems that it causes people coming from
other lisps.
>
> (defmacro with ((var val) &body body)
> "Eval body setting the global VAR to temporary VAL."
> (let ((zz (gensym "with")))
> `(let ((,zz ,var))
> (unwind-protect (progn (setq ,var ,val) ,@body)
> (setq ,var ,zz)))))
>
> How do I do the same for arbitrary number of global variables?
Just use the proper declarations.
> Why doesn't CL provide such functionality?
It does.
> Thanks.
> --
> Sam Steingold