Skip to contentSkip to conversation

static vs. dynamic scoping

DISCUSSION Eric Blake 2 participants 3 messages Nov 10, 2010 – Nov 15, 2010 2 messages not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

Eric Blake

author
#2 lore raw

[redirecting back to the list, so others can benefit]

Quoted 8 lines · Marc Herbert
Quoted 6 lines · Eric Blake

I'm trying to standardize the notion of local variables for the next revision of POSIX, but before I can do so, I need some feedback on two general aspects:
[...]
Here's a sample shell script that illustrates the difference between the two scoping methods.

Quoted 5 lines

Hi Eric,

I found your sample script quite confusing. To make your point, does
this script really need to:
- use unquoted language keywords as string values?

No; I could have used other strings.

Quoted 1 line

- use deprecated "typeset" instead of declare?

Yes - the current Austin Group thoughts are to standardize 'typeset' and NOT 'local', since 'typeset' can be used with arguments outside of functions, and more existing shells provide 'typeset' than 'local' (dash being the odd one out) or 'declare'. Shells can continue to provide 'local' as a synonym for the most basic use of typeset.

Quoted 1 line

- use the not (or less?) standard "function" keyword?

Yes - ksh93 ONLY supports function-local scoping when using the function keyword, rather than when using POSIX functions (although David Korn agreed that if POSIX standardizes function-local scoping, he'd make the next build of ksh support it in POSIX functions).

So, here's the example again, with those points addressed:

# Demonstrate ksh local scoping is static - requires ksh's 'function'

$ ksh -c 'function f1 { typeset a=temp; f2; echo "in f1: $a"; };
function f2 { echo "in f2: $a"; a=changed; }; a=global; f1; echo "top
level: $a"'
in f2: global
in f1: temp
top level: changed

# Demonstrate that with POSIX functions, ksh has global scoping

$ ksh -c 'f1 () { typeset a=temp; f2; echo "in f1: $a"; }; f2 () { echo
"in f2: $a"; a=changed; }; a=global; f1; echo "top level: $a"'in f2: temp
in f1: changed
top level: changed

# Demonstrate that dash local scoping is currently dynamic

$ dash -c 'f1 () { local a=temp; f2; echo "in f1: $a"; }; f2 () { echo
"in f2: $a"; a=changed; }; a=global; f1; echo "top level: $a"'
in f2: temp
in f1: changed
top level: global
Signature · 2 lines
Eric Blake   [email protected]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org
#3 lore raw
Quoted 52 lines · Eric Blake

[redirecting back to the list, so others can benefit]

Quoted 8 lines · Marc Herbert
Quoted 6 lines · Eric Blake

I'm trying to standardize the notion of local variables for the next revision of POSIX, but before I can do so, I need some feedback on two general aspects:
[...]
Here's a sample shell script that illustrates the difference between the two scoping methods.

Quoted 5 lines

Hi Eric,

I found your sample script quite confusing. To make your point, does
this script really need to:
- use unquoted language keywords as string values?

No; I could have used other strings.

Quoted 1 line

- use deprecated "typeset" instead of declare?

Yes - the current Austin Group thoughts are to standardize 'typeset' and NOT 'local', since 'typeset' can be used with arguments outside of functions, and more existing shells provide 'typeset' than 'local' (dash being the odd one out) or 'declare'. Shells can continue to provide 'local' as a synonym for the most basic use of typeset.

Quoted 1 line

- use the not (or less?) standard "function" keyword?

Yes - ksh93 ONLY supports function-local scoping when using the function keyword, rather than when using POSIX functions (although David Korn agreed that if POSIX standardizes function-local scoping, he'd make the next build of ksh support it in POSIX functions).

So, here's the example again, with those points addressed:

# Demonstrate ksh local scoping is static - requires ksh's 'function'

$ ksh -c 'function f1 { typeset a=temp; f2; echo "in f1: $a"; };
function f2 { echo "in f2: $a"; a=changed; }; a=global; f1; echo "top
level: $a"'
in f2: global
in f1: temp
top level: changed

# Demonstrate that with POSIX functions, ksh has global scoping

$ ksh -c 'f1 () { typeset a=temp; f2; echo "in f1: $a"; }; f2 () { echo
"in f2: $a"; a=changed; }; a=global; f1; echo "top level: $a"'in f2: temp
in f1: changed
top level: changed
Quoted 7 lines

# Demonstrate that dash local scoping is currently dynamic

$ dash -c 'f1 () { local a=temp; f2; echo "in f1: $a"; }; f2 () { echo
"in f2: $a"; a=changed; }; a=global; f1; echo "top level: $a"'
in f2: temp
in f1: changed
top level: global

Why is the debate static-vs-dynamic scoping coming up again? People like Ken Thompson, who wrote the very first UNIX shell, Douglas McIlroy, inventor of the UNIX pipelines and many others of the fathers of UNIX have criticized the concept of dynamic scoping in ksh88 loudly, in USENIX meetings and elsewhere. Even David Korn admitted that it was a grave design error and corrected it for the next major version of the korn shell, which became ksh93.

With this background I doubt any proposal for dynamic scoping will make it into the next POSIX standard. It's simply not considered a sane design for a modern computer language anymore and bash's emulation of ksh88's dynamic scoping can hardly be used as precedent in Austin Group proposals after ksh88 itself was abandoned in 1992.

Ced

Signature · 2 lines
Cedric Blancher <[email protected]>
Institute Pasteur
author
#4 lore raw
Quoted 2 lines · Cedric Blancher

Why is the debate static-vs-dynamic scoping coming up again?

Because before 'typeset' can be standardized in POSIX, we have to get consensus from all the shell implementers that they will agree to implement static scoping.

For ksh, the question is moot - ksh93 already does static only.

For dash, the question is valid - the current dash implementation is dynamic only, but given that switching to static only could probably be made more efficient, and dash values efficiency, it's a reasonable goal.

For bash and zsh, which currently are dynamic only, the problem stems that there are now a number of shell script libraries for these two shells that have exploited dynamic scoping, and which would break if we aren't careful to standardize something that can still allow dynamic scoping as an extension. In other words, this was a probe of the various shell implementers to figure out how easily static scoping can be added on after the fact to a dynamic scoping implementation, so that the shell could conform to a future POSIX revision that mandates static and permits dynamic as an extension.

Quoted 2 lines

With this background I doubt any proposal for dynamic scoping will make it into the next POSIX standard.

There's no desire for dynamic scoping in POSIX; David Korn has already made that point clear on the Austin Group mailing list. Rather, there is a desire for minimal effort for complying with a new POSIX requirement of static scoping on shells that currently lack it, as well as backwards compatibility for shells that wish to continue to provide dynamic scoping as an extension to the standard.

My take of the Austin Group list discussion is that the next revision of the standard is most likely to have consensus if it just mandates 'typeset' for static scoping, and leaves 'local' as an implementation extension for dynamic scoping. Please, chime in on the Austin Group conversation if you have something useful to add.

Signature · 2 lines
Eric Blake   [email protected]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org