I had to read the full "Yacas evaluation scheme" on the linked page to understand the quoted statement.
Back in the "good old days" (so I'm told), things like scoping rules were not taken for granted, and there were many ideas for how a variable name is mapped to a memory location.
Today, most languages have some notion of local variables, function parameters, and global variables that are checked in that order.
These are all scoped by static lexical rules.
Common Lisp uses similar rules, but it has dynamic variables (see DEFVAR) in place of global variables, where scope is determined by the function call stack.
By default, variables in Common Lisp are lexically scoped, similar to LocalSymbols and TemplateFunction in Yacas.
The Yacas design allows functions to be defined before the variables in the function body are defined.
Such undefined variables keep their name, and that name is looked up in the environment where the value is needed.
If the environment changes, then the value can also change.
In my book, this is more a feature of interpreted and some dynamic languages than it is a feature of functional languages or Lisp in particular.
So the undefined variables in Yacas have lookup similar to dynamic variables and calls to EVAL or PROGV in Common Lisp.
The design flaw mentioned in Yacas is most similar to the controversy surrounding Common Lisp's "unhygienic" macros.
The Scheme family of Lisp languages generally feature "hygienic" macro systems that avoid naming issues in macro definitions.
Other functional languages like Haskell use monads to provide similar "hygienic" features.
Common Lisp example:
Code: Select all
* (defvar *a* 1)
*A*
* *a*
1
* (let ((*a* 2)) *a*)
2
* (let ((*a* 3)) (eval '(list *a*)))
(3)