# Scope of variables in Pluto

**URL:** <https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413>\
**Category:** New to Julia\
**Tags:** package, pluto\
**Created:** [August 31, 2023, 4:57pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413 "2023-08-31T16:57:27Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 4:57pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/1 "2023-08-31T16:57:27Z")

</div>

Hi everybody!

I am new to Julia, POMDPs, and Pluto… and I am using all three to try and simulate a POMDP problem. I know that I am probably making some mistakes in my POMDP, but my immediate error is:

UndefVarError: `i` not defined

I am curious as to why I receive this error when ‘i’ is defined within the same Pluto cell. 🤔

I also receive warnings (image posted below) about the other POMDP variables s, r\_total, d, b as well.

Nowhere in my code are any of these variables defined globally.

I appreciate any insight that can help me to solve this challenge. 🥰

So far I have tried different browsers, including using incognito mode, and still receive this error.

If I comment out ‘i’, and all parts of the code that rely on ‘i’, then the next error I receive is "UndefVarError: ‘b’ not defined 🤦‍♂️ so I think that this points to scope of these variables defined within the begin / end block of the cell, and the scope within the while loop.

```julia
begin
	up = DiscreteUpdater(pomdp);
	b0 = uniform_belief(pomdp);
	s = rand(initialstate(pomdp));
	
	b = initialize_belief(up, b0);
	r_total = 0.0;
	d = 1.0;
	i = 0 # index of current bin
	while (!isterminal(pomdp, s)) && (i < 60)
	    determine_observations(i,1)
		a = action(policy, b)
	    s, o, r = @gen(:sp,:o,:r)(pomdp, s, a)
	    r_total += d*r
	    d *= discount(pomdp)
	    b = update(up, b, a, o)
		i += 1
	end
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/f/2f3a038deea2ec79b156bc7790221fd9f80d2fe7.jpeg)

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 31, 2023, 6:08pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/2 "2023-08-31T18:08:25Z")

</div>

There are several issues here, but basically there is confusion over if you are trying to use globals or not. In general, in Julia, you shouldn probably minimize the use of globals unless you really need them.

One solution is to use a `let` block to create a local scope around the loop.

```julia
i = let i = 0, d = 1.0, s = rand(initialstate(pomdp)) # etc
    while (!isterminal(pomdp, s)) && (i < 60)
    end
    i # or whatever variables you want to return  
end

```

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 6:46pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/3 "2023-08-31T18:46:07Z")

</div>

Thank you @mkitti for your response. I had no intention of using any global variables. Edit: In fact, I had not declared any of these variables outside of this cell in Pluto. The only things that exist outside of this cell is my function determine\_observations(), pomdp, and policy.

I was able to find [let blocks](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks) or keyword [let](https://docs.julialang.org/en/v1/base/base/#let) in julia documentation.

Can you explain to me what I had done wrong, or what I need to be aware of to avoid the need for let blocks?

---

<div class="post-metadata">

**Author:** ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)\
**Post date:** [August 31, 2023, 7:37pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/4 "2023-08-31T19:37:10Z")

</div>

There is a way to avoid `let` here, but I would recommend against it.

`begin` doesn’t create a new scope, so the variables defined in cell with a `begin` block are considered global. However, you can use `local` to restrict the scope of a single variable, so the following are equivalent:

```julia
julia> begin
           local x = 1
           x
       end
1

julia> isdefined(@ __MODULE__ , :x)
false

julia> let x = 2
           x
       end
2

julia> isdefined(@ __MODULE__ , :x)
false

```

My suggestion is: Don’t do this. As you probably noticed, Julia scope rules are awfully complicated, so the best thing to do here is to write small functions, or when prototyping, using `let`.

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [August 31, 2023, 7:37pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/5 "2023-08-31T19:37:23Z")

</div>

I’m not getting any errors like yours.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/5/d5faa3ee3522333189b8483bca79a307716071f6.png)

so I’m not sure I believe this:

> [@GenerallyClueless](#):
>
> Nowhere in my code are any of these variables defined globally.

Maybe you have another begin-end block somewhere which is also using a global `i`.

Try running a minimal, self-contained problem first and then expand it to the full problem, so it is easier to diagnose your issue.

> [@Please read: make it easier to help you](https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757):
>
> Welcome to the Julia Discourse! We are enthusiastic about helping Julia programmers, both beginner and experienced. This public service announcement (PSA) outlines best practices when asking for help. Following these points makes it easier for us to help you and more likely you’ll get a prompt, useful answer. Keywords are highlighted to make it easier to refer to specific points. Choose a descriptive title that captures the key part of your question, eg “plots with multiple axes” instead of …

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [August 31, 2023, 7:41pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/6 "2023-08-31T19:41:14Z")

</div>

I don’t use Pluto, but here the issue seems to be about what’s the definition of a global variable. This would require a really long answer, but just to be brief, take global variables as anything that is outside a function or a `let` block.

The word `begin` does nothing actually in your case, so all variables you define there are global variables. I think that you wanted to use `let` instead of `begin`, which is what you could have in mind when you were using `begin`.

More generally, the use of global variables is discouraged in all programming languages, but in Julia is way more problematic: it basically completely kills performance. Also, I’d recommend getting used to organizing your code in terms of functions, as it’s the most performant way to use Julia (not only in terms of syntax, but literally in terms of speed).

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 8:00pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/7 "2023-08-31T20:00:27Z")

</div>

Yes, thanks @Nathan_Boyer, I totally agree with your approach to troubleshooting 💯. I do have another function within the same Pluto notebook that also uses a while loop. There are also variables initialized outside of the while loop (within the same cell) that are used within the while loop for an index and other purposes. No problems running that code. The difference is that everything is initialized within the function… so maybe I will put all of this code inside a function too… rather than begin/end block. There is something specific to this block that is deceiving me… probably something simple because I am a n00b. 😅

I have tried other things like changing the variable names… like ‘i’ to ‘ii’ (and so forth) but it has not made a difference. The code looks straightforward and benign, so I am really puzzled 🤷

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 8:06pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/8 "2023-08-31T20:06:47Z")

</div>

Thanks @alfaromartino for your reply. I have used ‘i’ in other local contexts, but have not declared it globally. I stay away from globals … but I do use mutable structs 😳 … which if I understand correctly, are global by nature (once instantiated). I hope that mutable structs are OK from a performance and code cleanliness perspective.

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 8:08pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/9 "2023-08-31T20:08:24Z")

</div>

Thank you @savq

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 8:34pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/10 "2023-08-31T20:34:30Z")

</div>

I put the POMDP simulation code from this cell inside a function rather than using a begin/end block and the code was able to run without issue. 🎉

Thank you to everyone who has responded 🥰 to help me troubleshoot this.

I am still curious to learn why I had this challenge? Even when I broke the code into separate cells (8 cells total) to avoid using a begin/end block I still ran into the issue. I’m sure that I had to make some n00b mistake somewhere… but to receive the same error for both ‘i’ and ‘b’ (after commentintg out all 'i’s) … seems

```julia
function testPOMDP()
	
	up = DiscreteUpdater(pomdp); 
	b0 = uniform_belief(pomdp);
	s = rand(initialstate(pomdp));
	
	b = initialize_belief(up, b0);
	r_total = 0.0;
	d = 1.0;
	i = 0 # index of current bin
	while (!isterminal(pomdp, s)) && (i < 60)
	    determine_observations(i,1)
		a = action(policy, b)
	    s, o, r = @gen(:sp,:o,:r)(pomdp, s, a)
	    r_total += d*r
	    d *= discount(pomdp)
	    b = update(up, b, a, o)
		println("got to ",i, " with r_total ",r_total)
		i += 1
	end
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/a/fa80b23909a6a7e9911ea8a83ebc5ea4c96d2168.jpeg)

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [August 31, 2023, 9:00pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/11 "2023-08-31T21:00:26Z")

</div>

See the documentation [here](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#local-scope). If you scroll down, it explains when your message appears.

```julia
julia> code = """
       s = 0 # global
       for i = 1:10
           t = s + i # new local `t`
           s = t # new local `s` with warning
       end
       s, # global
       @isdefined(t) # global
       """;

julia> include_string(Main, code)
┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable.
└ @ string:4
ERROR: LoadError: UndefVarError: `s` not defined

```

The rules of scope change depending on how you run your code, which includes Pluto (I don’t use Pluto, but I’m guessing from your message that it follows the same rules as if you work non-interactively, which means executing the code through a file).

If you’re new to Julia, I’d recommend avoiding Pluto for now. Instead, use a code editor (e.g., VS Code) and run your script there (this is referred to as running your code interactively). When you work with for-loops and while loops inside a function, the rules are always the same, and that’s why you don’t get the error. Otherwise, you need to analyze some ambiguous cases. That’s another reason why the use of functions is preferred in Julia.

In any case, notice that you’re still using global variables in the function. Ask yourself “is there any variable I’m mentioning in the function’s body that isn’t part of the function’s argument or defined locally?”. If your answer is yes, then you’re using global variables. Examples in your code `pomdp` and `policy` (unless they’re functions, don’t what their definitions are, but I guess they’re variables defined outside the function).

---

<div class="post-metadata">

**Author:** ![GenerallyClueless](https://avatars.discourse-cdn.com/v4/letter/g/c37758/32.png) [@GenerallyClueless](https://discourse.julialang.org/u/GenerallyClueless)\
**Post date:** [August 31, 2023, 9:45pm UTC](https://discourse.julialang.org/t/scope-of-variables-in-pluto/103413/12 "2023-08-31T21:45:42Z")

</div>

Thank you again @alfaromartino. I thought this section of the docs link was particularly interesting: 📚

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/9/09b5f24ff4725c2483ee89337f26fc42e3220dd2.png)

In my code there are only two instance where I define “i” by assignment, and both are in local context.

Once within my testPOMDP() function (formerly begin/end block) and the other within a plotting function used to iterate a matrix. Both instances are within functions, so locally scoped. Other instances are when ‘i’ is used in for loops to iterate.

I think we can agree that somewhere these variables (‘i’ and ‘b’) are being viewed as global, but I am completely sure that I have not specifically declared them as such.

I agree that coding small functions was the right thing to do, and ultimately, when I put my POMDP simulation in function, was the easiest way to proceed. 😃

Thanks again!
