# "Locally global" variable?

**URL:** <https://discourse.julialang.org/t/locally-global-variable/60471>\
**Category:** General Usage\
**Tags:** scope\
**Created:** [May 3, 2021, 4:49pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471 "2021-05-03T16:49:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 3, 2021, 4:49pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/1 "2021-05-03T16:49:50Z")

</div>

Is there a way to make a julia variable _locally global_ (for the lack of a better word) ?

To give a little context, I am currently trying to implement some inter-process-communication using julia.  
With what I know (understand very little) about this process, I need to read a named pipe multiple times from a given server.  
My example code [here](https://discourse.julialang.org/t/how-to-correctly-stream-data-over-a-pipe-to-account-for-type-variability/60252) is shown again below

```julia
using MsgPack, Parameters, Sockets

struct TestStructure
    a::Int64
    b::Vector{Float64}
end

# Prepare MsgPack to understand "TestStructure" structures
MsgPack.msgpack_type(::Type{TestStructure}) = MsgPack.StructType()

function MsgPack_server()

    # Initialize named pipe server
    server = listen("\\\\.\\pipe\\JuliaPipe")
    # Keep waiting for instructions
    while true
        # Connect to server
        sock = accept(server)
        # Wait until reception job is finished
        while isopen(sock)
            # Read data
            msg = readline(sock)
            # De-code data
            test = unpack(msg, TestStructure) # <--- in the end how to replace this using information coming through the pipe
            # Print data
            println(test)
            # Close connection
            close(sock)
        end
        # Start new connection to server
        sock = accept(server)
        # Wait until send job is finished
        while isopen(sock)
            # Perform some computation
            test2 = TestStructure(3,rand(Float64,5))
            # Code data
            msg = pack(test2)
            # Write data to stream server
            write(sock, msg)
            flush(sock)
            # Close connection
            close(sock)
            # Print data
            println(test2)
        end
    return nothing
end

```

The variable `test` is nested in two `while`-loops so it is not accessible from a higher scope.  
However, for my use case, I would like to access such streamed variable, so I can actually use them in some computations. So, how should I make such variables accessible from another iteration of the second `while`-loop hence the _locally global_.

---

<div class="post-metadata">

**Author:** ![bashonubuntu](https://avatars.discourse-cdn.com/v4/letter/b/f19dbf/32.png) [@bashonubuntu](https://discourse.julialang.org/u/bashonubuntu)\
**Post date:** [May 3, 2021, 4:53pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/2 "2021-05-03T16:53:04Z")

</div>

You can use a `let` block

[https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks)

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 3, 2021, 4:58pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/3 "2021-05-03T16:58:27Z")

</div>

As far as I understand this (please correct me if I am wrong), a `let` block _protects_ a local declaration from a global one, and probably in the same manner protects the global variable from the local declaration.  
However, I can’t figure how it would help trespass such scope protection…

---

<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:** [May 3, 2021, 4:59pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/4 "2021-05-03T16:59:05Z")

</div>

You can use `local` on the level of of scope you want:

```julia
julia> function f()
         local x
         for i in 1:10
            for j in 1:10
               x = i*j
            end
         end
         x
       end
f (generic function with 1 method)

julia> f()
100

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 4, 2021, 8:06am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/5 "2021-05-04T08:06:56Z")

</div>

> [@BambOoxX](#):
>
> I would like to access such streamed variable, so I can actually use them in some computations. So, how should I make such variables accessible from another iteration of the second `while` -loop hence the _locally global_ .

You can use a `let` over a function, eg

```julia
let test = nothing
    function MsgPack_server()
        ...
    end
end

```

but frankly I would just refactor and pass it around explicitly, much cleaner.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 8:13am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/6 "2021-05-04T08:13:41Z")

</div>

What do you mean by

> I would just refactor and pass it around explicitly

As this is the very first time I implement IPC, it is surely a naive implementation, I am open for any advice 🙂

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 4, 2021, 8:15am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/7 "2021-05-04T08:15:28Z")

</div>

If you want to reuse `test`, pass it around as an argument, possibly in a container like `RefValue` if you want to modify it.

(Sorry if I am missing something about the example, it is not very clear).

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 8:27am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/8 "2021-05-04T08:27:47Z")

</div>

To clarify a bit my workflow with this program:

I am doing IPC in the following manner : `connect to pipe -> read stream -> do something with the streamed data`. Sometimes in send

- strings : which are used to determine what computation should be launched (within the `MsgPack_server` function)
- custom structures : which are used as arguments for the computations

Each time I send an information through the pipe, one iteration of the `while isopen(sock)` loop runs, making the passed data unavailable for the next iteration e.g. :

1. First iteration : a specific struct is sent over the pipe. `test` is of type `mystruct1` using the type I can store `test` with appropriate `if ...elseif ... end` blocks such that `ms1 = test`
2. Second iteration : a string is sent over the pipe, let’s say `test` is of type `String` and `test = "DoSomethingWithMs1"` . Again, with appropriate conditions, I can start a `ms2 = DoDomethingWithMs1(ms1)`. But for that I have to know `ms1`

So basically, I need persistence of previous-iteration variables inside my `MsgPack_server()` call.

I hope it is a bit clearer now.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 4, 2021, 8:30am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/9 "2021-05-04T08:30:11Z")

</div>

So, just have the first iteration return it, and pass it to the second iteration as an argument?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 8:41am UTC](https://discourse.julialang.org/t/locally-global-variable/60471/10 "2021-05-04T08:41:02Z")

</div>

I am sorry, I don’t see what you mean. Currently I am doing something like

```julia
while isopen(sock)
msg = readline(sock)
test = TypeAwareUnpack(msg)
if typeof(test) == String
    if test == "DoSomethingWithMs1"
        ms2 = DoSomethingWithMs1(ms1)
    end
else
    if typeof(test) == Mystruct1
        ms1 = test
    end
end

```

Is this what you are thinking about (at least that’s how I understand your last comment)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 4, 2021, 12:17pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/11 "2021-05-04T12:17:04Z")

</div>

> [@BambOoxX](#):
>
> Is this what you are thinking about

I am still not sure I fully understand the question. If

> [@BambOoxX](#):
>
> for my use case, I would like to access such streamed variable, so I can actually use them in some computations

then maybe wrap the code above in a function and also return `test`?

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 12:53pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/12 "2021-05-04T12:53:08Z")

</div>

I think I am starting to see where you are going with this, but in the end I am not sure if it will make much of a difference than using the `local` proposed by @lmiq.

Wrapping in a function would probably improve performance a bit though.  
Anyway, thanks for the advice.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [May 4, 2021, 3:36pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/13 "2021-05-04T15:36:33Z")

</div>

The decomposition that @Tamas_Papp is recommending will not only possibly improve performance, but will definitely increase reusability, composability, and maintainability by following the principle of separation of concerns. That is, separate the IPC logic from the application (ie., compute) logic.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 3:41pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/14 "2021-05-04T15:41:17Z")

</div>

As I said before, this is surely a naive implementation, and I am all ears for advice. I just do not see at the moment what this _decomposition_ would look like, that’s all. If you have an example for a good practice, feel free to post it 🙂 .

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [May 4, 2021, 3:47pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/15 "2021-05-04T15:47:19Z")

</div>

One approach would be split your function into two, each containing one of the inner while loops. Call one `readPipe` and the other `writePipe`. Then call those like this:

```julia
  data = readPipe()
  results = computeSomething(data)
  writePipe(results)

```

Then your outer while loop could wrap those, or better, put those three lines in a function and calling that function could be the body of your outer while loop.

Another approach could be to use three separate Tasks, two for reading and writing to the pipe and another for computing the results. The Tasks would communicate via Channels. [Asynchronous Programming · The Julia Language](https://docs.julialang.org/en/v1/manual/asynchronous-programming/)

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 4:51pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/16 "2021-05-04T16:51:51Z")

</div>

So you mean the overall code would look like

```julia
function readPipe(server)
    sock = accept(server)
    while isopen(sock)
        msg = readline(sock)
        data = unpack(msg)
        close(sock)
    end
    return data
end

function writePipe(server,data)
    sock = accept(server)
    while isopen(sock)
        msg = pack(sock, data)
        close(sock)
    end
end

function read_compute_write(server)
    data = readPipe(server)
    results = computeSomething(data)
    writePipe(server,results)
end

function MsgPack_server()
    server = listen("path_to_pipe")
    while true
        read_compute_write(server)
    end
end

```

?  
Thanks for the tip about tasks.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 5:07pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/17 "2021-05-04T17:07:45Z")

</div>

After writing my last post, I think I understand now how my first one was ambiguous.  
I actually need to reuse variables output by the `readPipe` in numerous iterations of the overall `while` and not necessarily in the subsequent `writePipe` e.g

First iteration : data in pipe is of type `Data1`

```julia
data1 = readPipe()

```

Second iteration : data in pipe is of type `Data2`

```julia
data2 = readPipe()

```

Third iteration : data in pipe is of type `String`

```julia
result1 = computeSomething(data1,string)

```

Fourth iteration : data in pipe is of type `String`

```julia
result2 = computeSomething(data1,result1,string)

```

So it feels like the previous code factorization is not applicable in this case (or more probably this factorization is a bit too aggressive) while the `local` works fine. Any ideas to improve this ?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [May 4, 2021, 5:15pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/18 "2021-05-04T17:15:29Z")

</div>

Your code between readPipe and writePipe should provide all the necessary logic for determining what actions to take based on the type(s). readPipe and writePipe are still decomposed properly. Don’t intertwine the app logic with the IO logic.

Options for how to accumulate the data read from readPipe would be to put the data in some combination of mutable structs, Dicts, (named) tuples, arrays, or others, depending on your problem. You can either pass the entire collection to computeSomething and have it deal with the multiple options, or have multiple computeSomething methods and deal with the options before calling it.

In short, break the problem into smaller distinct parts and solve those separately. You’ll discover that your problems and solutions will be reusable. Resist temptation to throw it all in a big pile because the pile will become unwieldy fast.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [May 4, 2021, 5:35pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/19 "2021-05-04T17:35:44Z")

</div>

So just to sum up a bit

- Messaging should only take / return one argument (if server is omitted) : the byte package / the data passed
- Filtering conditions based on `data` may be performed inside or outside of `computeSomething` as convenience.
- Variables that should be accessible in the main loop should be so through an appropriate container. For instance

```julia
mutable struct MyOverallContainer
    data1::Data1
    data2::Data2
    result1::Result1
end

```

Which would then be passed and modified by each `computeSomething` call.  
By the way I think this would not work for me because all of my structures are actually immutables so I wouldn’t know how to initialize this starting `MyOverallContainer`, but a `Dict` would surely work.

Do you agree with this summary ?

> [@Jeff\_Emanuel](#):
>
> In short, break the problem into smaller distinct parts and solve those separately. You’ll discover that your problems and solutions will be reusable. Resist temptation to throw it all in a big pile because the pile will become unwieldy fast.

Yeah, that was my plan, but I just came up with this code like few hours of work ago, so understanding was the priority.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [May 4, 2021, 5:43pm UTC](https://discourse.julialang.org/t/locally-global-variable/60471/20 "2021-05-04T17:43:33Z")

</div>

Yes the summary looks good. Immutable state is usually “a good thing”.

[Next page](https://discourse.julialang.org/t/locally-global-variable/60471.md?page=2)
