# How to prevent using global arrays in iteration in the module

**URL:** <https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857>\
**Category:** General Usage\
**Created:** [August 5, 2021, 4:53am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857 "2021-08-05T04:53:43Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 5, 2021, 4:53am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/1 "2021-08-05T04:53:43Z")

</div>

I have an a little detailed question about how to prevent using global array in iterations in the module. Hopefully someone could give some advice on how to prevent using global arrays.

```
module Mod
global AAA=Array{Float64,1}(undef, 999999999) # 999999999 is just to say the array is big. Its size is actually a variable which needs to be read in from an input file, the size is not a fixed number. 
for i in 1:100
      f(AAA, AAAupdate) # function f take in AAA, update it and output the updated array as AAAupdate
      g(AAAupdate,AAA) # function g take in the updatedAAA, and update it again to make a new AAA, and output the new AAA as AAA.        
end
end

```

As we can see, for each i loop,

the big array AAA first need to be input to function f, then updated to AAAupdate.

then function g takein the AAAupdate array, and further update it and form an updated array AAA.

Then in the next loop, the newly updated AAA will be read in function f again, and the process repeat 100 times.

Finally, after the 100 loops, AAA will be completely updated.

So my question is, in this case, again since Julia discourage global stuff, then, is there ways to prevent making AAA a global array?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 5, 2021, 7:40am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/2 "2021-08-05T07:40:40Z")

</div>

Just pass it to your functions:

```julia
function main()
    AAA = zeros(9_999_999_999)
    f!(AAA)
    g!(AAA)
    return AAA
end

```

then you just need to define your `f!` and `g!` functions accordingly. Note that I appended a bang `!` to the function name to indicate that it mutates its arguments - this is a naming convention in Julia, not a syntactic transformation (i.e. if I omit the bang it still mutates). Example:

```julia
julia> function f!(x)
           x .+= 1
       end
f! (generic function with 1 method)

julia> function g!(x)
           x .*= 3
       end
g! (generic function with 1 method)

julia> function main()
           AAA = zeros(5)
           f!(AAA)
           g!(AAA)
           return AAA
       end
main (generic function with 1 method)

julia> main()
5-element Vector{Float64}:
 3.0
 3.0
 3.0
 3.0
 3.0

```

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 5, 2021, 7:43am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/3 "2021-08-05T07:43:08Z")

</div>

Julia modules are libraries. There should not be logic depending on user input in a module.

Looks like you’re trying to use a module as a subroutine which is the first thing that’s wrong, not the globals in said module.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 5, 2021, 8:04am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/4 "2021-08-05T08:04:49Z")

</div>

Thank you very much.

1. About Julia, then what is the Julia way to do such a thing?
2. About Fortran, Is there a better way to do it in Fortran?

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 5, 2021, 8:09am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/5 "2021-08-05T08:09:09Z")

</div>

Thank you very much.  
I have a loop or iteration as you can see in my example, inside which the AAA is updated repeatedly.  
But in your code, it seems there is no loop, am I missing something?

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 5, 2021, 8:11am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/6 "2021-08-05T08:11:45Z")

</div>

Sorry that was a simplified example, but a loop wouldn’t change much:

```julia
julia> function main()
           AAA = zeros(5)
           for i ∈ 1:2
               f!(AAA)
               g!(AAA)
           end
           return AAA
       end
main (generic function with 1 method)

julia> main()
5-element Vector{Float64}:
 12.0
 12.0
 12.0
 12.0
 12.0

```

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 5, 2021, 10:15am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/7 "2021-08-05T10:15:24Z")

</div>

I have interpreted that `AAAupdate` is a temporary variable used as a workspace and the size of `AAAupdate` is determined from the size of `AAA`.

In this case, it is terribly inconvenient to fix the sizes of `AAA` and `AAAupdate` by hardcoding them in the module.

To avoid this, you can prepare functions to set the initial values of `AAA` and `AAAupdate` in the module, and use them outside the module.

The basic pattern is as follows:

```julia
module Foo
struct Board{...} ...including state and tmp... end
function initialboard(...) ...; Board(...) end
function update!(board::Board, niters) ...update state with tmp... end
end

# Construct initial board as a global variable
board = Foo.initialboard(...)

# Update the board by the `Foo.update!` method
Foo.update!(board, 1000)

```

**Working example: Game of Life**

Jupyter notebook: [https://github.com/genkuroki/public/blob/main/0014/Game%20of%20Life.ipynb](https://github.com/genkuroki/public/blob/main/0014/Game%20of%20Life.ipynb)

The size of the internal temporary workspace `tmp` is automatically determined by the size of the given `state` of `board`.

> **module LifeGame (53 lines)**
>
> ```julia
> module LifeGame
> 
> using Plots
> using ProgressMeter
> 
> struct Board{T}
> state::T
> tmp::T
> end
> Board(state) = Board(state, similar(state))
> function fivexfive(n=200)
> state = zeros(Int8, n, n)
> m = n ÷ 2
> state[m-2:m+2, m-2:m+2] .= [1 1 1 0 1; 1 0 0 0 0; 0 0 0 1 1; 0 1 1 0 1; 1 0 1 0 1]
> Board(state)
> end
> randboard(n=200) = Board(rand(Int8[0, 1], n, n))
> 
> P(i, m) = ifelse(i == m, 1, i+1)
> Q(i, m) = ifelse(i == 1, m, i-1)
> function _update!(v, u)
> m, n = size(u)
> @inbounds for j in 1:n, i in 1:m
> i₊, i₋, j₊, j₋ = P(i, m), Q(i, m), P(j, n), Q(j, n)
> N = u[i₋,j₋] + u[i,j₋] + u[i₊,j₋] + u[i₋,j] + u[i₊,j] + u[i₋,j₊] + u[i,j₊] + u[i₊,j₊]
> v[i,j] = N == 3 ? 1 : (N == 2 && !iszero(u[i,j])) ? 1 : 0
> end
> end
> 
> function update!(board::Board, niters=1)
> state, tmp = board.state, board.tmp
> for _ in 1:niters÷2
> _update!(tmp, state)
> _update!(state, tmp)
> end
> if isodd(niters)
> _update!(tmp, state)
> state .= tmp
> end
> end
> 
> function gif!(board::Board, niters, nskips=1; gifname="life.gif", fps=20, size=(240, 240))
> prog = Progress(niters, 0)
> anim = @animate for t in 1:niters
> heatmap(board.state; size, colorbar=false, ticks=false, axis=false, frame=false)
> update!(board, nskips)
> next!(prog)
> end
> gif(anim, gifname; fps)
> end
> 
> end
> 
> ```

```julia
boardrandom = LifeGame.randboard()
LifeGame.gif!(boardrandom, 500; gifname="liferandom.gif")

```

```julia
Progress: 100%|█████████████████████████████████████████| Time: 0:00:26

```

![liferandom](https://global.discourse-cdn.com/julialang/original/3X/3/5/35f597996991e478c018dad3ad31f9ee79aef626.gif)

```julia
board5x5 = LifeGame.fivexfive()
LifeGame.gif!(board5x5, 2000; gifname="life5x5.gif", fps=60)

```

```julia
Progress: 100%|█████████████████████████████████████████| Time: 0:01:05

```

![life5x5](https://global.discourse-cdn.com/julialang/original/3X/b/a/ba9c38303563b702dfffdfd0ea4a97d5ab672dba.gif)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 5, 2021, 11:37am UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/8 "2021-08-05T11:37:09Z")

</div>

> [@CRquantum](#):
>
> About Fortran, Is there a better way to do it in Fortran?

Also in Fortran passing variables as parameters is a good idea for code reuse and readability. What is common to share as global variables are truly constant data (the speed of light, the planck constant, etc). For these, use `const` in Julia.

In Julia, however, that is not only a good idea, but turns out to be very important to ensure performance. In Fortran performance is not dependent on that pattern. However, the comparison is not exactly fair. In Julia, by following that pattern, the function is used independent of the data in a typical section. For example:

```julia
### this module would be finally in a package
julia> module MyModule
         const hbar = 6.62e-34 # this is really constant
         function f!(x)
           for i in eachindex(x)
             x[i] = hbar*(x[i] + 1)
           end
         end
         return nothing
       end
Main.MyModule

julia> #### now the user side of things

julia> using .MyModule

julia> x = rand(1000);

julia> MyModule.f!(x)

julia> x[1]
1.2190537919428275e-33

```

In Fortran, for the user to provide the `x` array, it must be an input variable of the program, so how the user interacts with the code is completely different. But in both cases it is a good practice to use shared values in global scope only if they are constants. And everything else should be passed as parameters.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 5, 2021, 4:59pm UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/9 "2021-08-05T16:59:41Z")

</div>

Thank you very much.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 5, 2021, 5:25pm UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/10 "2021-08-05T17:25:11Z")

</div>

Was there anything wrong in the example I posted?

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 5, 2021, 8:53pm UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/11 "2021-08-05T20:53:15Z")

</div>

That is fine, thank you very much!

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 5, 2021, 9:44pm UTC](https://discourse.julialang.org/t/how-to-prevent-using-global-arrays-in-iteration-in-the-module/65857/12 "2021-08-05T21:44:40Z")

</div>

> [@CRquantum](#):
>
> You example seems does not have a loop.

No.

The function `LifeGame.gif!(board, niters; ...)` in my example contains the for loop updating `niters` times the global variables initialized by `boardrandom = LifeGame.randboard()` and `board5x5 = LifeGame.fivexfive()` outside the module `LifeGame` and plotting each step to gif animations.

In the module LifeGame:

> [@genkuroki](#):
>
> ```julia
> function gif!(board::Board, niters, nskips=1; gifname="life.gif", fps=20, size=(240, 240))
> prog = Progress(niters, 0)
> anim = @animate for t in 1:niters
> heatmap(board.state; size, colorbar=false, ticks=false, axis=false, frame=false)
> update!(board, nskips)
> next!(prog)
> end
> gif(anim, gifname; fps)
> end
> 
> ```

Outside the module LifeGame:

> [@genkuroki](#):
>
> ```julia
> boardrandom = LifeGame.randboard()
> LifeGame.gif!(boardrandom, 500; gifname="liferandom.gif")
> 
> ```

> [@genkuroki](#):
>
> ```julia
> board5x5 = LifeGame.fivexfive()
> LifeGame.gif!(board5x5, 2000; gifname="life5x5.gif", fps=60)
> 
> ```

`LifeGame.update!(board, niters)` is not used in the example, but can update a `LifeGame.Board` type variable without plotting.

In the module LifeGame:

> [@genkuroki](#):
>
> ```julia
> function update!(board::Board, niters=1)
> state, tmp = board.state, board.tmp
> for _ in 1:niters÷2
> _update!(tmp, state)
> _update!(state, tmp)
> end
> if isodd(niters)
> _update!(tmp, state)
> state .= tmp
> end
> end
> 
> ```

The array `tmp`, which is used as a temporary workspace, is created by the constructor of `LifeGame.Board` objects.

> [@genkuroki](#):
>
> ```julia
> struct Board{T}
> state::T
> tmp::T
> end
> Board(state) = Board(state, similar(state))
> 
> ```

**Example of `LifeGame.update!`:** Glider

Updating a global variable with a for loop can be done by passing it as an argument to a function containing a for loop.

```julia
state = Int8[
    0 0 0 0 0 0 0
    0 0 0 0 0 0 0
    0 0 0 0 0 0 0
    0 0 0 0 0 0 0
    0 1 1 0 0 0 0
    1 0 1 0 0 0 0
    0 0 1 0 0 0 0
]
board = LifeGame.Board(state)
board.state

```

```julia
7×7 Matrix{Int8}:
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 1 1 0 0 0 0
 1 0 1 0 0 0 0
 0 0 1 0 0 0 0

```

↓  
↓ update the global variable `board` 12 times  
↓ by the for loop in the function `LifeGame.update!`  
↓

```julia
LifeGame.update!(board, 12)
board.state

```

```julia
7×7 Matrix{Int8}:
 0 0 0 0 0 0 0
 0 0 0 0 1 1 0
 0 0 0 1 0 1 0
 0 0 0 0 0 1 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0

```

↓  
↓ update and animate the global variable `board`  
↓

```julia
LifeGame.gif!(board, 27; gifname="lifeglider.gif", fps=5)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/a/c/ace63cbf80e94795a5fcd3ec23947a601578f895.gif)

Have fun!

Jupyter notebook: [https://github.com/genkuroki/public/blob/main/0014/Game%20of%20Life.ipynb](https://github.com/genkuroki/public/blob/main/0014/Game%20of%20Life.ipynb)
