[Ecls-list] Problems with updating an external global variable
Matthew Mondor
mm_lists at pulsar-zone.net
Wed Jul 24 06:53:59 UTC 2013
On Wed, 24 Jul 2013 11:08:45 +0900
Dietrich Bollmann <dietrich at formgames.org> wrote:
> What do you mean by "dynamic/special variable"?
This is not ECL specific, but Common Lisp and various other lisps
support variables with dynamic extent. Sorry if this is already
obvious to you and a misunderstanding, or if this CL-general topic is
off-topic on this list.
The following links might be useful:
https://en.wikipedia.org/wiki/Dynamic_scope#Dynamic_scoping
https://en.wikipedia.org/wiki/Common_lisp#Dynamic
http://www.lispworks.com/documentation/HyperSpec/Body/03_af.htm
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#dynamic_extent
It's a convention in Common Lisp to name special/dynamic variables
using a * prefix and suffix, and these are usually defined using DEFVAR
or DEFPARAMETER (the difference being that DEFVAR will not reset the
value on reload/reevaluation if it's already set). These are in a
sense like global variables for SETF, but whenever a local binding is
created using LET, they have dynamic scope, that is, every callee will
also see the new overriding binding, and SETF will only affect that
level of binding. Unlike lexical scope, which is only valid within the
immediate scope (like C lexical variables, usually created using LET in
CL), and global scope (like C global variables), dynamic scope is
implemented using a stack internally, and is very useful for the
control of state and context. Example:
(let ((*standard-output* my-stream))
...)
Therefore *STANDARD-OUTPUT*, *TERMINAL-IO*, etc, may be dynamically
bound and serve as though it was a function parameter, but which
survives through function calls without needing to be passed as
arguments to them. The example above redirects the *STANDARD-OUTPUT*
stream to MY-STREAM for the scope of that LET block, therefore calls to
functions such as FORMAT or WRITE using T as the stream designator (see
http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#stream_designator),
could now pass through MY-STREAM, until the scope of that LET ends.
In another thread of execution, another active dynamic binding for
those special variables can also exist, thus special variables are also
commonly used for thread-specific data, and can be dynamically rebound
by new threads as need be (on Common Lisp implementations which support
threads, of course).
I guess that you could consider them an orthogonal arguments stack, not
coupled to function arguments, and yet with a controled scope, unlike
global variables. Using them, it's also possible to pass extra
parameters around though opaque third party code, without modifying it.
So for instance, as a possible design choice in an HTTPd, the context
such as *CONTEXT*, *CONNECTION*, *REQUEST*, etc, may be dynamically
bound variables instead of having to pass a context object down to every
function explicitely...
--
Matt
More information about the ecl-devel
mailing list