Skip to content

Commit ac09416

Browse files
nathanrboyerlazarusA
authored andcommitted
Add Scoping Beginner Summary to Manual (JuliaLang#54500)
The Scope of Variables section of the manual is good and thorough but overwhelming to beginners. This PR is motivated by several questions on discourse ([1](https://discourse.julialang.org/t/best-solution-to-julias-soft-scope-problem/70199/14), [2](https://discourse.julialang.org/t/global-variable-issue/108288), [3](https://discourse.julialang.org/t/why-does-the-soft-scope-warning-not-appear-in-a-nested-loop/72646)) where scoping behavior was an immediate confusion and turn off to using Julia.
1 parent cc1ef60 commit ac09416

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

doc/src/manual/variables-and-scoping.md

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,60 @@ introduce a "soft scope", which affects whether
1616
[shadowing](https://en.wikipedia.org/wiki/Variable_shadowing)
1717
a global variable by the same name is allowed or not.
1818

19-
### [Scope constructs](@id man-scope-table)
19+
!!! Note Rough Summary
20+
21+
Variables defined in global scope may be undefined in inner local scopes,
22+
depending on where the code is run, in order to balance safety and convenience.
23+
The hard and soft local scoping rules define the interplay between global and local variables.
24+
25+
However, variables defined only in local scope behave consistently in all contexts.
26+
If the variable is already defined, it will be reused. If the variable is not defined,
27+
it will be made available to the current and inner scopes (but not outer scopes).
28+
29+
!!! Tip A Common Confusion
30+
31+
If you run into an unexpectedly undefined variable,
32+
33+
```julia
34+
# Print the numbers 1 through 5
35+
i = 0
36+
while i < 5 # ERROR: UndefVarError: `i` not defined
37+
i += 1
38+
println(i)
39+
end
40+
```
41+
42+
a simple fix is to change all global variable definitions into local definitions
43+
by wrapping the code in a `let` block or `function`.
44+
45+
```julia
46+
# Print the numbers 1 through 5
47+
let i = 0
48+
while i < 5 # Now `i` is defined in the inner scope of the while loop
49+
i += 1
50+
println(i)
51+
end
52+
end
53+
```
54+
55+
This is a common source of confusion when writing procedural scripts,
56+
but it becomes a non-issue if code is moved inside functions
57+
or executed interactively in the REPL.
58+
59+
See also the [`global`](@ref) and [`local`](@ref) keywords
60+
to explicitly achieve any desired scoping behavior.
61+
62+
### [Scope Constructs](@id man-scope-table)
2063

2164
The constructs introducing scope blocks are:
2265

23-
| Construct | Scope type | Allowed within |
24-
|:----------|:-----------|:---------------|
66+
| Construct | Scope Type Introduced | Scope Types Able to Contain Construct |
67+
|:----------|:----------------------|:--------------------------------------|
2568
| [`module`](@ref), [`baremodule`](@ref) | global | global |
2669
| [`struct`](@ref) | local (soft) | global |
27-
| [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local |
2870
| [`macro`](@ref) | local (hard) | global |
29-
| functions, [`do`](@ref) blocks, [`let`](@ref) blocks, comprehensions, generators | local (hard) | global, local |
71+
| [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local |
72+
| [`function`](@ref), [`do`](@ref), [`let`](@ref), [comprehensions](@ref man-comprehensions), [generators](@ref man-generators) | local (hard) | global, local |
3073

3174
Notably missing from this table are
3275
[begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation)

0 commit comments

Comments
 (0)