A critic of Guido's blog on Python's lambda
Marcin 'Qrczak' Kowalczyk
qrczak at knm.org.pl
Sat May 13 13:44:01 CEST 2006
Alexander Schmolck <a.schmolck at gmail.com> writes:
> I'd like to see a demonstration that using the same binding syntax
> for special and lexical variables buys you something apart from bugs.
There are 3 fundamental operations related to plain mutable variables:
A1. Making a new mutable variable with an initial value.
A2. Getting the current value.
A3. Setting the new value.
and 4 operations related to dynamically scoped variables:
B1. Making a new dynamic variable with an initial value.
B2. Getting the current value.
B3. Setting the new value.
B4. Local rebinding with a new initial value.
If you don't ever use B4, dynamic variables behave exactly like plain
variables. For this reason I see no point in distinguishing A2 from B2,
or A3 from B3. Dynamic variables are a pure extension of plain variables
by providing an additional operation.
Distinguishing the syntax of A1 and B1 is natural: somehow it must be
indicated what kind of variable is created.
Mutability is orthogonal to dynamic scoping. It makes sense to have a
variable which is like a plain variable but without A3, and a variable
which is like a dynamic variable but without B3, although it doesn't
provide anything new, only allows to express more constraints with a
potential for optimization. I won't consider them here.
Common Lisp does something weird: it uses the same syntax for A1 and B4,
where the meaning is distinguished by a special declaration. Here is
Directly named plain variables:
A1. (let ((name value)) body) and other forms
A3. (setq name value), (setf name value)
First-class dynamic variables:
B2. (symbol-value variable)
B3. (set variable value), (setf (symbol-value variable) value)
B4. (progv `(variable) `(value) body)
Directly named dynamic variables:
B1. (defvar name value), (defparameter name value)
B3. (setq name value), (setf name value)
B4. (let ((name value)) body) and other forms
Dynamic variables in Lisp come in two flavors: first-class variables
and directly named variables. Directly named variables are always
global. You can convert a direct name to a first-class variable by
Plain variables have only the directly named flavor and they are
always local. You can emulate the first-class flavor by wrapping a
variable in a pair of closures or a closure with dual getting/setting
interface (needs a helper macro in order to be convenient). You can
emulate a global plain variable by wrapping a dynamic variable in a
symbol macro, ignoring its potential for local rebinding. You can
emulate creation of a new first-class variable by using a dynamic
variable and ignoring its potential for local rebinding, but this
can't be used to refer to an existing directly named plain variable.
In order to create a plain variable, you must be sure that its name is
not already used by a dynamic variable in the same scope.
So any essential functionality is possible to obtain, but the syntax
is very irregular.
__("< Marcin Kowalczyk
\__/ qrczak at knm.org.pl
More information about the Python-list