# Debugging in VS Code has difference variable scope behavior

**URL:** <https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226>\
**Category:** VS Code\
**Tags:** debug\
**Created:** [April 28, 2022, 7:09pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226 "2022-04-28T19:09:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![msena](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/msena/32/13076_2.png) [@msena](https://discourse.julialang.org/u/msena)\
**Post date:** [April 28, 2022, 7:09pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/1 "2022-04-28T19:09:31Z")

</div>

Hi,  
I am trying to debug some code and upon some experimentation it seems that the debugger in visual studio code has a different scoping behavior than when running stuff no the REPL? Consider the following example (maybe I am missing something either on the behavior of the REPL or the debugger)

```julia
a = 1
b = 2

i = 0
while i < 2
    println(a)
    i += 1
end

```

When I run this on the repl, it runs fine. When I run it on the debugger, I get

```julia
Exception has occurred: UndefVarError

UndefVarError: i not defined

```

It seems that the repl behavior automatically refers to the global variable i, but this is not the case in the debugger?  
Any clarification is appreciated.  
Thanks

---

<div class="post-metadata">

**Author:** ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)\
**Post date:** [April 28, 2022, 7:13pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/2 "2022-04-28T19:13:31Z")

</div>

Your problem might be related to global vs. non-global scope.

A helpful resource is the [scope](https://docs.julialang.org/en/v1/manual/variables-and-scoping/) page in the official documentation.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 28, 2022, 8:39pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/3 "2022-04-28T20:39:10Z")

</div>

> [@moeddel](#):
>
> A helpful resource is the [scope](https://docs.julialang.org/en/v1/manual/variables-and-scoping/) page in the official documentation.

And more precisely, you can look in that page for the difference in behavior of “soft scopes” between “interactive contexts” (like the REPL) and “non-interactive” ones (like running — or in the OP’s case case debugging — files). There is a section dedicated to the motivation for such [soft scopes](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#On-Soft-Scope).

It’s unfortunate that while debugging a file, VS Code displays the error message copied by @msena , but it does not show the clarifying warning that is seen if you try to run the file in the REPL (non-interactively):

```plaintext
┌ Warning: Assignment to `i` in soft scope is ambiguous because a global
variable by the same name exists: `i` will be treated as a new local.
Disambiguate by using `local i` to suppress this warning or `global i` to assign
to the existing global variable.

```

---

<div class="post-metadata">

**Author:** ![msena](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/msena/32/13076_2.png) [@msena](https://discourse.julialang.org/u/msena)\
**Post date:** [April 28, 2022, 10:04pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/4 "2022-04-28T22:04:48Z")

</div>

But why does the debugger recognize the global variable `a` but not the global variable `i`?

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 28, 2022, 10:20pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/5 "2022-04-28T22:20:12Z")

</div>

Because `a` is “read” but not assigned in the loop, so it assumes that it must be something defined outside (there is no other possibility). On the other hand, `i` is assigned inside the loop (`i += 1` is the same as `i = i + 1`), so the rules presented in the cited page apply:

> [@](#):
>
> When `x = <value>` occurs in a local scope, Julia applies the following rules to decide what the expression means based on where the assignment expression occurs and what `x` already refers to at that location:
> 
> 1. **Existing local:** If `x` is _already a local variable_ , then the existing local `x` is assigned;
> 2. **Hard scope:** If `x` is _not already a local variable_ and assignment occurs inside of any hard scope construct (i.e. within a `let` block, function or macro body, comprehension, or generator), a new local named `x` is created in the scope of the assignment;
> 3. **Soft scope:** If `x` is _not already a local variable_ and all of the scope constructs containing the assignment are soft scopes (loops, `try` / `catch` blocks, or `struct` blocks), the behavior depends on whether the global variable `x` is defined:
> 
> - if global `x` is _undefined_ , a new local named `x` is created in the scope of the assignment;
> - if global `x` is _defined_ , the assignment is considered ambiguous:
> - in _non-interactive_ contexts (files, eval), an ambiguity warning is printed and a new local is created;
> - in _interactive_ contexts (REPL, notebooks), the global variable `x` is assigned.
> 
> You may note that in non-interactive contexts the hard and soft scope behaviors are identical except that a warning is printed when an implicitly local variable (i.e. not declared with `local x` ) shadows a global. In interactive contexts, the rules follow a more complex heuristic for the sake of convenience. This is covered in depth in examples that follow.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 28, 2022, 10:36pm UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/6 "2022-04-28T22:36:18Z")

</div>

Or put it another way: the problem is not that the global variable `i` is not recognized, but that a local `i` is also created (by the assignment operation `i = <something>`), and it shadows the existing global. So `i = i + 1` is interpreted as “take the value of local `i`, sum 1 and put that result into local `i`”. But the first part “take the value of local `i`” cannot be done, because it was not yet defined.

Perhaps you were confused by getting an `UndefVarError`, taking it as if it meant that global `i` is undefined. But that’s not the point. It is the undefined local `i` what triggers that error. The warning cited above may help to understand it, but unfortunately you couldn’t see it in the debugger.

---

<div class="post-metadata">

**Author:** ![msena](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/msena/32/13076_2.png) [@msena](https://discourse.julialang.org/u/msena)\
**Post date:** [May 13, 2022, 1:02am UTC](https://discourse.julialang.org/t/debugging-in-vs-code-has-difference-variable-scope-behavior/80226/7 "2022-05-13T01:02:02Z")

</div>

Thanks @heliosdrm , this is very helpful!
