On Wed, 21 Feb 2024 at 08:09, Chet Ramey <chet.ra...@case.edu> wrote:
> On 2/20/24 4:11 AM, Martin D Kealey wrote: > > Ideally each function invocation would have its own variable namespace, > > only using the global namespace as a fall-back, but that creates > > complications with exported variables, so let's take baby steps to get > there. > > That doesn't work with dynamic scoping at all. > Yes, that's exactly the point, to *avoid* dynamic scoping. I want the equivalent of Perl's "my", rather than Perl's "local". Perhaps I should clarify that I'm using "global namespace" to mean what Perl calls a "package" (except Bash has only one), and that it *includes* the dynamic effects of dynamic "local" statements. Therefore "using the global namespace as a fall-back" means precisely that variables that are not explicitly lexically scoped would continue to behave as they do now. Code that currently relies on dynamic scoping would continue to work, while new code can avoid the craziness that comes from "everything is global, even when we claim it's local" and "unset can even mess with the poor protection afforded by 'local'". -Martin PS: Lexical variable scope implies that nested functions require multiple 'local' symbol tables to be active concurrently, effectively as in a chain. That in turn means the local variables associated with a function invocation would need to outlive that invocation if there are lexically nested functions that access them. If lexical variable declarations were declarative (immediately effective during parsing) rather than procedural (only becoming effective when the flow of control passes over them), that would be advantageous: a single local symbol table could be kept with the parse tree for each function, with an index into a per-invocation storage array. Then some time in the future, symbol look-ups could be done during the parsing phase, leaving a 'local reference by index' entry in the parse tree. (Having a fixed symbol table implies that the behaviour of the 'unset' command would subtly change; for the global symbol table it would continue to behave as now, but for the symbol tables associated with functions, it would place an 'unset' marker in the slot, rather than deleting the name. There may be corner cases where that's a detectable change, but since it's opt-in I think that's acceptable. And that means some new mechanism to implement 'upvar' would be needed.) Being effective during parsing would argue for 'local' being a keyword, albeit one that mostly behaves as if it's a command, but I can see that some would argue that it's too much change, so I wouldn't object to leaving 'local' as it is and defining a new keyword for this purpose; my preference would be one of 'my', 'var', or 'use local' (where 'use' is a general 'during parsing' keyword).