# Seek for a detailed description on scopes and modules

**URL:** <https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442>\
**Category:** New to Julia\
**Created:** [October 17, 2018, 1:42pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442 "2018-10-17T13:42:52Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![alegarra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alegarra/32/5787_2.png) [@alegarra](https://discourse.julialang.org/u/alegarra)\
**Post date:** [October 17, 2018, 1:42pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/1 "2018-10-17T13:42:52Z")

</div>

I am an R / Fortran programmer trying to understand scopes in Julia. I know the great debate local/global, but what I’m looking for is a _document_ (resource) where the actual rules for scopes are described with examples. Also for modules that `use` modules. Is there any such document? The official docs at [Julia Documentation · The Julia Language](https://docs.julialang.org/en/v1/) are complete but rather terse. Thanks.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [October 17, 2018, 2:06pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/2 "2018-10-17T14:06:48Z")

</div>

Not sure if you missed it or just had further questions, but scope is documented in the manual here: [https://docs.julialang.org/en/stable/manual/variables-and-scoping/#scope-of-variables-1](https://docs.julialang.org/en/stable/manual/variables-and-scoping/#scope-of-variables-1). If you scroll down, there are some examples included.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 17, 2018, 2:15pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/3 "2018-10-17T14:15:07Z")

</div>

The constructs `let`, `for`, `while`, `try`, `catch`, comprehensions, `function` and any syntax for a function (lambdas, `do` blocks) introduce new scopes.

When you see `x = ` in a scope body, then it does one of two things:

1. If there is already an outer _local_ variable called `x`, it assigns to that;
2. Otherwise it declares a new `x` local to this new scope and assigns to it.

It does not matter if there is an outer _global_ named `x` or not: it will never be assigned unless you write `global x` to declare that you want `x` to refer to the global named `x`.

We can crowd-source some examples.

---

<div class="post-metadata">

**Author:** ![alegarra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alegarra/32/5787_2.png) [@alegarra](https://discourse.julialang.org/u/alegarra)\
**Post date:** [October 17, 2018, 2:26pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/4 "2018-10-17T14:26:39Z")

</div>

so you have _global_ and a telescopic hierarchy of _local_ ?

just a minimal example that confuses me. How does the function know that there is a Dict called tablefact ?

```nohighlight
function ffact(i)
    tablefact[i]=i*tablefact[i-1]
    return tablefact[i]
end

global tablefact=Dict{Int64,Float64}()
tablefact[0]=1
for j in 1:10
    println(ffact(j))
end

println(tablefact)

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 17, 2018, 2:36pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/5 "2018-10-17T14:36:15Z")

</div>

> [@alegarra](#):
>
> so you have _global_ and a telescopic hierarchy of _local_ ?

Yes, there is a global scope in each module and a hierarchy of local scopes introduced by each scope-introducing construct.

> [@alegarra](#):
>
> How does the function know that there is a Dict called tablefact ?

You never assign to `tablefact` in the `ffact` body so it must refer to a global.

---

<div class="post-metadata">

**Author:** ![alegarra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alegarra/32/5787_2.png) [@alegarra](https://discourse.julialang.org/u/alegarra)\
**Post date:** [October 17, 2018, 3:03pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/6 "2018-10-17T15:03:09Z")

</div>

> [@StefanKarpinski](#):
>
> You never assign to `tablefact` in the `ffact` body so it must refer to a global.

you mean, I never assign to the _whole_ `tablefact` Dict ? Only to one of its cells?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 17, 2018, 3:05pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/7 "2018-10-17T15:05:52Z")

</div>

Yes, that is not assignment, it is mutation of the `Dict` object, which is very different:

> [@Explicit denotation of variability and immutability](https://discourse.julialang.org/t/explicit-denotation-of-variability-and-immutability/8686/51):
>
> There are the following assignment-like syntaxes:
> 
> - `x = ...` is assignment. The name `x` is bound to the value that the `...` evaluates to. Local bindings never leak out of their scope. It doesn’t matter what `x` was bound to before this happens, that _value_ is not affected in any way. No object is mutated by this and no other binding besides `x` is changed.
> 
> - `x.f = ...` is equivalent to `setproperty!(x, :f, ...)` which, by default mutates the object `x` by changing its field `f` to the value of the expression `...` . If `x` is visible in another scope or by another bindings, this change will be seen everywhere. No bindings are changed by this.
> 
> - `x[i] = ...` is equivalent to `setindex!(x, ..., i)` which, for arrays mutates the array `x` by changing its `i` th slot to refer to the value of the expression `...` . If `x` is visible in another scope or by another bindings, this change will be seen everywhere. No bindings are changed by this.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [October 17, 2018, 4:22pm UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/8 "2018-10-17T16:22:57Z")

</div>

> [@StefanKarpinski](#):
>
> When you see `x =` in a scope body, then it does one of two things:
> 
> 1. If there is already an outer _local_ variable called `x` , it assigns to that;
> 2. Otherwise it declares a new `x` local to this new scope and assigns to it.

I’d like to expand on the second point: Declaring a local `x` is not an instruction, it is a syntactic annotation of the entire scope. Whether an `x` is local to the scope is independent of what your code does, and can be decided from the syntax tree alone: If `x` ever appears on the left-hand side of an assignment (`x = ...` or `x += ...`, _not_ `x.foo = ...` or `x[i] = ...` or `x .= ...`), and there is no `global x` declaration, then it is a local variable.

If you think about declaration as a thing that is done at runtime, then you will get confused because the declaration travels back in time from unreachable positions:

```julia
julia> x=1;

julia> function f()
       return x
       #x=2
       end;

julia> f()
1

julia> function f2()
       return x
       x=2
       end;

julia> f2()
ERROR: UndefVarError: x not defined

```

In reality, the problem of `f2()` is not that `x` is not defined; julia knows perfectly well that you declared a local variable called `x`, which shadows the global `x`. Rather it is that you tried to use the value before initializing it.

---

<div class="post-metadata">

**Author:** ![KW2P](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kw2p/32/18659_2.png) [@KW2P](https://discourse.julialang.org/u/KW2P)\
**Post date:** [October 14, 2020, 5:34am UTC](https://discourse.julialang.org/t/seek-for-a-detailed-description-on-scopes-and-modules/16442/9 "2020-10-14T05:34:15Z")

</div>

> [@StefanKarpinski](#):
>
> You never assign to `tablefact` in the `ffact` body so it must refer to a global.

There’s the answer to my problem. Thank you!

I have a module containing several functions. All the functions need to refer to a global variable defined in the module but outside of the functions. Let’s call it x. After hours of trial and error, I still didn’t understand what was going on and why only one version worked correctly.

It seemed to me that I should use the global qualifier at each place that x is used is used, but that doesn’t work. Julia complains about extraneous “global” keywords. What I didn’t notice was that the configuration that works has “global” at the point in one of the functions where the value of x is assigned. In all other occurences, x is used but not assigned.

The fact that Julia makes an assumption did not occur to me.

So, if x is assigned a new value inside of a function, you have to use “global”. If x is used and not defined within the function, Julia assumes it must be the “outer x” that’s being referred to.

My intuition says that’s a good way to introduce subtle bugs, but at least I now understand it. I’d much prefer having to specify “global” at each place that the outer variable is used or assigned in an inner scope.

Thank you again for solving my mystery. 🙂
