Global and nonlocal statements#
Code Example
Runnable Example in Jac and JacLib
# Global and Nonlocal Statements
let x = "global x";
let a = 1, b = 2;
def test_global {
# Global with single name
global x;
x = "modified global x";
print(x);
}
def test_multiple_globals {
# Global with multiple names
global a, b;
a = 10;
b = 20;
print(f"{a} {b}");
}
def outer {
y = "outer y";
def inner {
# Nonlocal with single name
nonlocal y;
y = "modified by inner";
print(y);
}
print(y);
inner();
print(y);
}
def outer_multi {
p = 1;
q = 2;
r = 3;
def inner_multi {
# Nonlocal with multiple names
nonlocal p, q, r;
p = 10;
q = 20;
r = 30;
}
print(f"{p} {q} {r}");
inner_multi();
print(f"{p} {q} {r}");
}
with entry {
print(x);
test_global();
print(x);
print(f"{a} {b}");
test_multiple_globals();
print(f"{a} {b}");
outer();
outer_multi();
}
Jac Grammar Snippet
Description
Global and Nonlocal Statements
The global
and nonlocal
statements control variable scope, allowing functions to modify variables from outer scopes rather than creating local shadows.
Module-Level Global Variables
Lines 3-4 declare module-level global variables. These variables exist at module scope and are accessible throughout the module.
Global Statement - Single Variable
Lines 6-11 demonstrate the global
statement. Line 8: global x
declares that x
refers to the module-level global variable (line 3). Without this statement, line 9's assignment would create a new local variable instead of modifying the global.
Global Statement - Multiple Variables
Lines 13-19 show declaring multiple global variables. Line 15: global a, b
is more concise than separate global
statements for each variable.
Nonlocal Statement - Single Variable
Lines 21-34 demonstrate the nonlocal
statement for nested functions. Line 26: nonlocal y
declares that y
refers to the enclosing function's variable (line 22), not a global or new local. Line 27's assignment modifies the outer function's y
.
Nonlocal Statement - Multiple Variables
Lines 36-52 show declaring multiple nonlocal variables. Line 43: nonlocal p, q, r
modifies all three variables from the enclosing scope.
Scope Resolution Rules
Without global
or nonlocal
, assignments create new local variables. These keywords alter this behavior:
Keyword | Accesses | Scope Level | Use Case |
---|---|---|---|
global |
Module-level variables | Global | Modify module state from functions |
nonlocal |
Enclosing function variables | Enclosing | Closures, nested function state |
Execution Flow
Lines 54-65 demonstrate the execution and effects:
Variable Modification Flow
flowchart TD
Start([Assignment in Function]) --> Check{global or<br/>nonlocal<br/>declared?}
Check -->|global| ModGlobal[Modify module-level<br/>global variable]
Check -->|nonlocal| ModEnclosing[Modify enclosing<br/>function variable]
Check -->|Neither| CreateLocal[Create new<br/>local variable]
ModGlobal --> Done([Assignment Complete])
ModEnclosing --> Done
CreateLocal --> Done
Scope Levels Example
flowchart TD
Global[Global Scope<br/>x, a, b] --> Outer1[outer function<br/>y variable]
Outer1 --> Inner1[inner function<br/>accesses y with nonlocal]
Global --> Outer2[outer_multi function<br/>p, q, r variables]
Outer2 --> Inner2[inner_multi function<br/>accesses p,q,r with nonlocal]
Global --> TestGlobal[test_global function<br/>accesses x with global]
Common Patterns
Modifying module state:
Closure with state:
Multiple scope levels:
Key Differences
Global vs Nonlocal:
- global
reaches to module level (skips all intermediate scopes)
- nonlocal
reaches to the nearest enclosing function scope (not global)
- global
can declare variables that don't exist yet
- nonlocal
requires the variable to exist in an enclosing scope
Important Rules
- Without declaration: Assignments create new local variables
- With global: Assignments modify module-level variables
- With nonlocal: Assignments modify enclosing function's variables
- Reading vs Writing: You can read outer scope variables without declarations; declarations are needed for assignment
- Multiple names: Both statements support comma-separated variable lists