# Difference in behaviour between REPL and debugger

**URL:** https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101
**Category:** New to Julia
**Created:** [July 16, 2024, 1:35pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101 "2024-07-16T13:35:17Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![seb](https://avatars.discourse-cdn.com/v4/letter/s/8edcca/32.png) [@seb](https://discourse.julialang.org/u/seb)
#### Post date: [July 16, 2024, 1:35pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/1 "2024-07-16T13:35:17Z")

</div>

I am encountering an issue with Julia where code will run correctly in the debugger but throws an error when called from the REPL, which I don’t understand. A simple example of this is the code below:

```julia
function test()
    i = 0
    while i <= 1
        if i > 0
            var += 1
        end
        i += 1
        var = 1
    end
end

```

If I run `@run test()` then the function runs successfully, whereas if I just run `test()` I get the error

```julia
julia> test()
ERROR: UndefVarError: `var` not defined
Stacktrace:
 [1] test()
   @ Main ~/Code/asqp/temp_delete.jl:6
 [2] top-level scope
   @ REPL[1]:1

```

The error indicates that the variable `var` doesn’t exist, but it _should_ be initialized on the first run through the while loop (the condition `if i < 0` will fail on the first iteration) before it is referenced.

Could anyone please explain why I am observing this behavior?

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [July 16, 2024, 1:46pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/2 "2024-07-16T13:46:01Z")

</div>

The compiler is correct that `var` isn’t defined when it’s encountered in the code. The debugger is probably more forgiving due to its interpretative nature. Adding a `local var` solves the issue.

---

<div class="post-metadata">

### Author: ![seb](https://avatars.discourse-cdn.com/v4/letter/s/8edcca/32.png) [@seb](https://discourse.julialang.org/u/seb)
#### Post date: [July 16, 2024, 3:28pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/3 "2024-07-16T15:28:39Z")

</div>

Thanks for the reply. I assume the it’s something to do with the scope in the while loop and it being different between the debugger and REPL, but am interested if someone could explain why.

---

<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: [July 16, 2024, 7:18pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/4 "2024-07-16T19:18:15Z")

</div>

I’m a little unclear on what the debugger is doing here but this sounds like a bug in its interpreter. `var` is local to each iteration of the while loop, so any time the body of the if block executes it should be an undef var error.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [July 16, 2024, 7:22pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/5 "2024-07-16T19:22:41Z")

</div>

If the debugger is incorrectly modeling the scoping rules and just lazily adding variables whenever it encounters a new one, the execution makes sense. In that (wrong) semantic, the `if` is never entered so a non-existent binding is never read from (and thus no `UndefVarError` is thrown). Instead, `var` is just set to `1` later.

EDIT: Hm, this could be argued either way, so that either the compiler or the debugger are in the wrong here. If the debugger version is correct, the compiler would have to prove that in every possible execution trace, `var` is initialized before it’s read from in order not to throw an `UndefVarError`. If the compiler is correct here, the debugger would have to explore paths more eagerly and check whether it could be the case that the variable is read from before it’s initialized, irrespective of the actual values.

Either way, something is buggy.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 16, 2024, 9:38pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/6 "2024-07-16T21:38:54Z")

</div>

> [@Sukera](#):
>
> the `if` is never entered

It does on the 2nd `i=1` iteration, that’s when the compiled code throws an error. I think this is an unambiguous debugger issue because “In loops and comprehensions, new variables introduced in their body scopes are freshly allocated for each loop iteration.” `var` in the 1st `i=0` iteration and its assignment are thus unrelated to `var` in the 2nd `i=1` iteration; this has important implications for closures capturing iteration-local variables. To make a variable persist across iterations, it needs to exist in the scope the loop is in, like `i`. I don’t know how the debugger’s interpreter works, but would it be difficult to do a variable declaration pass\* then toss out loop-local variables every iteration?

```julia
julia> function test()
           i = 0
           while i <= 1
               @show i
               if i > 0
                   print("if i > 0 reached: ")
                   var += 1
                   @show i, var
               end
               i += 1
               var = 1
               @show i, var
           end
       end
test (generic function with 1 method)

julia> test()
i = 0
(i, var) = (1, 1)
i = 1
if i > 0 reached: ERROR: UndefVarError: `var` not defined
...
julia> function test2()
           i = 0
           local var # even without a value it's good enough
           while i <= 1
               @show i
               if i > 0
                   print("if i > 0 reached: ")
                   var += 1
                   @show i, var
               end
               i += 1
               var = 1
               @show i, var
           end
       end
test2 (generic function with 1 method)

julia> test2()
i = 0
(i, var) = (1, 1)
i = 1
if i > 0 reached: (i, var) = (1, 2)
(i, var) = (2, 1)

```

\*Funnily, you are allowed to put the `local var` declaration at the end because variable declarations are not executed at runtime, the parser or lowerer just puts them in scopes. If you write an assignment there instead, like `var=10`, that also serves to declare a variable in the scope but it will also instantiate a value at runtime that is returned by the method. Whether part of an assignment or not, declarations not adhering to the runtime order require a pass.

---

<div class="post-metadata">

### Author: ![seb](https://avatars.discourse-cdn.com/v4/letter/s/8edcca/32.png) [@seb](https://discourse.julialang.org/u/seb)
#### Post date: [July 18, 2024, 12:58pm UTC](https://discourse.julialang.org/t/difference-in-behaviour-between-repl-and-debugger/117101/7 "2024-07-18T12:58:09Z")

</div>

Thanks for the responses. Where should I go from here then? Should I raise it as an issue on the debugger github page?
