|
From: Robert D. <rob...@gm...> - 2024-02-17 22:09:29
|
While working through fixing up the share test suite to correct
results the lexical symbols branch, I observed a few different ways of
using nonlexical symbols in the various share packages. I am guessing
that we may bump into similar examples when people are writing code
for a hypothetical lexically-equipped Maxima.
(1) use of global variables to communicate between functions aside
from function arguments, e.g. f() := block([y: ...], g()); g() :=
h(y);
(2) calling a global function and assigning the return value to a
local variable of the same name, e.g. block([length], length:
length(...), ...)
(3) calling assoc with a first argument which is a local variable and
the second argument contains global variables, e.g. f([a]) :=
block([foo], assoc('foo, a)); f(foo = 123);
(4) substitution of a local variable into an expression containing
global variables, e.g. f(e) := block([x], subst ('x = ..., e)); f(x +
1);
Other variations are certainly possible, these are just the ones I
remember seeing. Item 1 was probably the most common.
There are workarounds for all of these. For (1), make the global
variables into function arguments, or, more hackishly, declare them
nonlexical. For (2), give the local variable a different name, e.g.
my_length instead of length. For (3), give the local variable a
different name, e.g. foo_value instead of foo, or just don't make it a
local variable if its value is never used. For (4), supply the name of
the variable of interest along with the expression to obviate the need
to guess the variable, e.g. f(e, var) := subst(var = ..., e); These
are all (with the exception of the nonlexical declaration) a good idea
anyway.
These are not too important in themselves but I think they're useful
to talk about since they represent existing programming constructs
which work differently in the presence of lexical symbols.
best
Robert
|