@@ -26,24 +26,35 @@ introducing scope blocks are:
26
26
27
27
.. _man-scope-table :
28
28
29
- +--------------------------------+----------------------------------------------------------------------------------+
30
- | Scope name | block/construct introducing this kind of scope |
31
- +================================+==================================================================================+
32
- | :ref: `global <man-global >` | module, baremodule, at interactive prompt (REPL) |
33
- +--------------------------------+------------------------------+---------------------------------------------------+
34
- | :ref: `local <man-local-scope >` | :ref: `soft <man-soft-scope >` | for, while, comprehensions, |
35
- | | | try-catch-finally, let |
36
- | +------------------------------+---------------------------------------------------+
37
- | | :ref: `hard <man-hard-scope >` | functions (either syntax, anonymous & do-blocks), |
38
- | | | type, immutable, macro |
39
- +--------------------------------+------------------------------+---------------------------------------------------+
40
-
41
- Notably missing from this table are :ref: `begin blocks
42
- <man-compound-expressions>` and :ref: `if blocks
43
- <man-conditional-evaluation>`, which do *not * introduce new scope
44
- blocks. All three types of scopes follow somewhat different rules
45
- which will be explained below as well as some extra rules for
46
- certain blocks.
29
+ * Scope blocks that may nest only in other global scope blocks:
30
+
31
+ - global scope
32
+
33
+ + module, baremodule
34
+
35
+ + at interactive prompt (REPL)
36
+
37
+ - local scope (don't allow nesting)
38
+
39
+ + type, immutable, macro
40
+
41
+ * Scope blocks which may nest anywhere (in global or local scope):
42
+
43
+ - local scope
44
+
45
+ + for, while, try-catch-finally, let
46
+
47
+ + functions (either syntax, anonymous & do-blocks)
48
+
49
+ + comprehensions, broadcast-fusing
50
+
51
+
52
+ Notably missing from this table are
53
+ :ref: `begin blocks <man-compound-expressions >`
54
+ and :ref: `if blocks <man-conditional-evaluation >`,
55
+ which do *not * introduce new scope blocks.
56
+ Both types of scopes follow somewhat different rules
57
+ which will be explained below.
47
58
48
59
Julia uses `lexical scoping <https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping >`_,
49
60
meaning that a function's scope does not inherit from its caller's
@@ -117,24 +128,29 @@ changed within their global scope and not from an outside module.
117
128
Note that the interactive prompt (aka REPL) is in the global scope of
118
129
the module ``Main ``.
119
130
131
+ Within the global scopes, the `global ` keyword is never necessary,
132
+ although allowed.
133
+
134
+
120
135
.. _man-local-scope :
121
136
122
137
Local Scope
123
138
-----------
124
139
125
- A new local scope is introduced by most code-blocks, see above
126
- :ref: `table <man-scope-table >` for a complete list. A local scope
127
- *usually * inherits all the variables from its parent scope, both for
128
- reading and writing. There are two subtypes of local scopes, hard and
129
- soft, with slightly different rules concerning what variables are
130
- inherited. Unlike global scopes, local scopes are not namespaces,
140
+ A new local scope is introduced by most code blocks (see above
141
+ :ref: `table <man-scope-table >` for a complete list).
142
+ A local scope inherits all the variables from a parent local scope,
143
+ both for reading and writing.
144
+ Additionally, the local scope inherits all globals that are assigned
145
+ to in its parent global scope block (if it is surrounded by a global `if ` or `begin ` scope).
146
+ Unlike global scopes, local scopes are not namespaces,
131
147
thus variables in an inner scope cannot be retrieved from the parent
132
148
scope through some sort of qualified access.
133
149
134
- The following rules and examples pertain to both hard and soft local
135
- scopes. A newly introduced variable in a local scope does not
136
- back-propagate to its parent scope. For example, here the `` z `` is not
137
- introduced into the top-level scope:
150
+ The following rules and examples pertain to local scopes.
151
+ A newly introduced variable in a local scope does not
152
+ back-propagate to its parent scope.
153
+ For example, here the `` z `` is not introduced into the top-level scope:
138
154
139
155
.. doctest ::
140
156
@@ -155,17 +171,17 @@ using the ``local`` keyword:
155
171
156
172
.. doctest ::
157
173
158
- julia> x = 0;
174
+ julia> x = 0
159
175
160
176
julia> for i = 1:10
161
- local x
177
+ local x # this is the default
162
178
x = i + 1
163
179
end
164
180
165
181
julia> x
166
182
0
167
183
168
- Inside a local scope a new global variable can be defined using the
184
+ Inside a local scope a global variable can be assigned to by using the
169
185
keyword ``global ``:
170
186
171
187
.. doctest ::
@@ -183,7 +199,7 @@ keyword ``global``:
183
199
parent local scope.
184
200
185
201
The location of both the ``local `` and ``global `` keywords within the
186
- scope block is irrelevant. The following is equivalent to the last
202
+ scope block is irrelevant. The following is equivalent to the last
187
203
example (although stylistically worse):
188
204
189
205
.. doctest ::
@@ -196,71 +212,22 @@ example (although stylistically worse):
196
212
julia> z
197
213
10
198
214
199
- Multiple global or local definitions can be on one line and can also
200
- be paired with assignments:
215
+ Multiple global or local definitions can be on one line (or split across several lines)
216
+ and can also be paired with assignments:
201
217
202
218
.. doctest ::
203
219
204
220
julia> for i = 1:10
205
221
global x = i, y, z
206
- local a = 4, b, c = 1
222
+ local a = 4, b,
223
+ c = 1
207
224
end
208
225
226
+ Local scopes are introduced by most block keywords,
227
+ with notable exceptions of `begin ` and `if `.
209
228
210
- .. _man-soft-scope :
211
-
212
- Soft Local Scope
213
- ^^^^^^^^^^^^^^^^
214
-
215
- In a soft local scope, all variables are inherited from its parent
216
- scope unless a variable is specifically marked with the keyword
217
- ``local ``.
218
-
219
- Soft local scopes are introduced by for-loops, while-loops,
220
- comprehensions, try-catch-finally-blocks, and let-blocks. There
221
- are some extra rules for :ref: `let-blocks <man-let-blocks >` and for
222
- :ref: `for-loops and comprehensions <man-for-loops-scope >`.
223
-
224
- In the following example the ``x `` and ``y `` refer always to the same
225
- variables as the soft local scope inherits both read and write
226
- variables:
227
-
228
- .. doctest ::
229
-
230
- julia> x, y = 0, 1;
231
-
232
- julia> for i = 1:10
233
- x = i + y + 1
234
- end
235
-
236
- julia> x
237
- 12
238
-
239
- Within soft scopes, the `global ` keyword is never necessary, although
240
- allowed. The only case when it would change the semantics is
241
- (currently) a syntax error:
242
-
243
- .. doctest ::
244
-
245
- julia> let
246
- local j = 2
247
- let
248
- global j = 3
249
- end
250
- end
251
- ERROR: syntax: `global j `: j is local variable in the enclosing scope
252
- ...
253
-
254
- .. _man-hard-scope :
255
-
256
- Hard Local Scope
257
- ^^^^^^^^^^^^^^^^
258
-
259
- Hard local scopes are introduced by function definitions (in all their
260
- forms), type & immutable-blocks, and macro-definitions.
261
-
262
- In a hard local scope, all variables are inherited from its parent
263
- scope unless:
229
+ In a local scope, all variables are inherited from its parent
230
+ global scope block unless:
264
231
265
232
- an assignment would result in a modified *global * variable, or
266
233
- a variable is specifically marked with the keyword ``local ``.
@@ -270,12 +237,12 @@ writing:
270
237
271
238
.. doctest ::
272
239
273
- julia> x, y = 1, 2;
240
+ julia> x, y = 1, 2
274
241
275
242
julia> function foo()
276
243
x = 2 # assignment introduces a new local
277
- return x + y # y refers to the global
278
- end;
244
+ return x + y # y refers to the global
245
+ end
279
246
280
247
julia> foo()
281
248
4
@@ -285,69 +252,88 @@ writing:
285
252
286
253
An explicit ``global `` is needed to assign to a global variable:
287
254
288
- .. doctest ::
255
+ .. sidebar :: Avoiding globals
289
256
290
- julia> x = 1;
257
+ Avoiding changing the value of global variables is considered by many
258
+ to be a programming best-practice.
259
+ One reason for this is that remotely changing the state of global variables in other
260
+ modules should be done with care as it makes the local behavior of the program hard to reason about.
261
+ This is why the scope blocks that introduce local scope require the ``global ``
262
+ keyword to declare the intent to modify a global variable.
291
263
292
- julia> function foobar()
293
- global x = 2
294
- end;
264
+ .. doctest ::
295
265
296
266
julia> foobar();
297
267
298
268
julia> x
299
269
2
300
270
301
- Note that *nested functions * can behave differently to functions
302
- defined in the global scope as they can modify their parent scope's
271
+ Note that *nested functions * can also modify their parent scope's
303
272
*local * variables:
304
273
305
274
.. doctest ::
306
275
307
- julia> x, y = 1, 2;
276
+ julia> x, y = 1, 2
308
277
309
- julia> function baz ()
278
+ julia> function foo ()
310
279
x = 2 # introduces a new local
311
280
function bar()
312
281
x = 10 # modifies the parent's x
313
282
return x + y # y is global
314
283
end
315
284
return bar() + x # 12 + 10 (x is modified in call of bar())
316
- end;
285
+ end
317
286
318
- julia> baz ()
319
- 22
287
+ julia> foo ()
288
+ 22 # (global x and y unchanged)
320
289
321
- julia> x, y
322
- (1,2)
290
+ The reason to allow *modifying local * variables of parent scopes in
291
+ nested functions is to allow constructing `closures
292
+ <https://en.wikipedia.org/wiki/Closure_%28computer_programming%29> `_
293
+ which have a private state, for instance the ``state `` variable in the
294
+ following example:
295
+
296
+ .. doctest ::
297
+
298
+ julia> let
299
+ state = 0
300
+ global counter
301
+ counter() = state += 1
302
+ end
303
+
304
+ julia> counter()
305
+ 1
323
306
324
- The distinction between inheriting global and local variables for
325
- assignment can lead to some slight differences between functions
326
- defined in local vs. global scopes. Consider the modification of the
307
+ julia> counter()
308
+ 2
309
+
310
+ See also the closures in the examples in the next two sections.
311
+
312
+ The distinction between inheriting global scope and nesting local scope
313
+ can lead to some slight differences between functions
314
+ defined in local vs. global scopes for variable assignments.
315
+ Consider the modification of the
327
316
last example by moving ``bar `` to the global scope:
328
317
329
318
.. doctest ::
330
319
331
- julia> x, y = 1, 2;
332
-
320
+ julia> x, y = 1, 2
333
321
334
322
julia> function bar()
335
323
x = 10 # local
336
324
return x + y
337
- end;
325
+ end
338
326
339
- julia> function quz ()
327
+ julia> function foo ()
340
328
x = 2 # local
341
329
return bar() + x # 12 + 2 (x is not modified)
342
- end;
343
-
344
- julia> quz()
345
- 14
330
+ end
346
331
347
- julia> x, y
348
- (1,2)
332
+ julia> foo()
333
+ 14 # as x is not modified anymore.
334
+ # (x and y unchanged)
349
335
350
- Note that above subtlety does not pertain to type and macro
336
+ Note that the above nesting rules do not pertain to type and macro
351
337
definitions as they can only appear at the global scope.
352
338
There are special scoping rules concerning the evaluation of default
353
339
and keyword function arguments which are described in the
@@ -384,9 +370,9 @@ positive integers are even or odd:
384
370
385
371
.. doctest ::
386
372
387
- julia> even(n) = n == 0 ? true : odd(n- 1);
373
+ julia> even(n) = n == 0 ? true : odd(n - 1);
388
374
389
- julia> odd(n) = n == 0 ? false : even(n- 1);
375
+ julia> odd(n) = n == 0 ? false : even(n - 1);
390
376
391
377
julia> even(3)
392
378
false
@@ -396,43 +382,8 @@ positive integers are even or odd:
396
382
397
383
Julia provides built-in, efficient functions to test for oddness and evenness
398
384
called :func: `iseven ` and :func: `isodd ` so the above definitions should only be
399
- taken as examples.
400
-
401
- Hard vs. Soft Local Scope
402
- ^^^^^^^^^^^^^^^^^^^^^^^^^
403
-
404
- Blocks which introduce a soft local scope, such as loops, are
405
- generally used to manipulate the variables in their parent scope.
406
- Thus their default is to fully access all variables in their parent
407
- scope.
408
-
409
- Conversely, the code inside blocks which introduce a hard local scope
410
- (function, type, and macro definitions) can be executed at any place in
411
- a program. Remotely changing the state of global variables in other
412
- modules should be done with care and thus this is an opt-in feature
413
- requiring the ``global `` keyword.
385
+ taken as examples of scope, not usage.
414
386
415
- The reason to allow *modifying local * variables of parent scopes in
416
- nested functions is to allow constructing `closures
417
- <https://en.wikipedia.org/wiki/Closure_%28computer_programming%29> `_
418
- which have a private state, for instance the ``state `` variable in the
419
- following example:
420
-
421
- .. doctest ::
422
-
423
- julia> let
424
- state = 0
425
- global counter
426
- counter() = state += 1
427
- end;
428
-
429
- julia> counter()
430
- 1
431
-
432
- julia> counter()
433
- 2
434
-
435
- See also the closures in the examples in the next two sections.
436
387
437
388
.. _man-let-blocks :
438
389
0 commit comments