Re: "locally special" variables in Lisp



Pascal Bourguignon <pjb@xxxxxxxxxxxxxxxxx> writes:

sankymoron@xxxxxxxxx writes:

Pascal Bourguignon wrote:
sankymoron@xxxxxxxxx writes:
nice. thanks. makes perfect sense. any practical use of this
functionality?

What functionality?

I come from C/C++ background, and haven't seen dynamically scoped local
variables before. So I was wondering what would be a practical
application of this feature?

In Common Lisp, all the global variables are dynamic.
(Those defined by DEFVAR and DEFPARAMETER).

These global dynamic variables are used as "knobs", or global parameters.
If they didn't exist, they'd have to be passed down thru a lot of functions.

For example, all the *PRINT- variables:
LISP> (apropos "*PRINT-" "CL")

*PRINT-ARRAY* variable
*PRINT-BASE* variable
*PRINT-CASE* variable
*PRINT-CIRCLE* variable
*PRINT-ESCAPE* variable
*PRINT-GENSYM* variable
*PRINT-LENGTH* variable
*PRINT-LEVEL* variable
*PRINT-LINES* variable
*PRINT-MISER-WIDTH* variable
*PRINT-PPRINT-DISPATCH* variable
*PRINT-PRETTY* variable
*PRINT-RADIX* variable
*PRINT-READABLY* variable
*PRINT-RIGHT-MARGIN* variable

are used by all (or most) the output functions.

So if they didn't exist, they'd have to be passed all to all functions
that eventually call an output function. (Unless of course we had
global lexical scope). Anyways the advantage of the dynamic scope is
that it allows us to bound a different value "temporarily":

(progn
(format t "~3,0F: ~A~%" *print-base* 42)
(let ((*print-base* 6))
(format t "~3,0F: ~A~%" *print-base* 42))
(format t "~3,0F: ~A~%" *print-base* 42))

prints:
10.: 42
6.: 110
10.: 42

The value 10 doesn't disappear when we bind 6 to *print-base*, it's
only temporarily shadowed. But the function format see the value 6
while the program is executing the LET, even thru the format function
is not defined in the lexical scope of this LET.

This shadowing technique is interesting when we have exceptional exits
(including errors) since the variable recovers it's normal value
automatically:

(progn
(format t "~3,0F: ~A~%" *print-base* 42)
(ignore-errors
(let ((*print-base* 6))
(format t "~3,0F: ~A~%" *print-base* 42)
(error "Damn")))
(format t "~3,0F: ~A~%" *print-base* 42))

prints:
10.: 42
6.: 110
10.: 42

--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.

The OP was asking about locally-special variables, not dynamic
variables in general.
.