# I define t, then in a loop I'm told it's undefined, why?

**URL:** https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258
**Category:** New to Julia
**Created:** [June 12, 2020, 10:39am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258 "2020-06-12T10:39:56Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)
#### Post date: [June 12, 2020, 10:39am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/1 "2020-06-12T10:39:56Z")

</div>

I’ve written a Julia script that should be using Simpson’s rule to approximate the solution to:

\displaystyle \int\_0^{-\pi} \dfrac{dy}{\sqrt{-\frac{2g}{l} \sin{y}}}

and compare it to the result obtained by QuadGK. But I’m getting an error that makes no sense to me. Namely I’m getting the error:

```julia
UndefVarError: t not defined

Stacktrace:
 [1] top-level scope at /data/GitHub/mine/math/julia-scripts/Simpson's_rule_pendulum_integral.jl:56
 [2] top-level scope at In[2]:1

```

and here’s the kicker, t is defined as equalling 0 at line 54. Here’s my script:

```julia
# This script essentially finds the time taken for a
# simple pendulum that starts with zero velocity at the 
# positive x-axis to reach the negative x-axis (theta=-pi)
# using Simpson's rule
# t is time and y is theta
using Pkg;

Pkg.add("SpecialFunctions")
Pkg.add("QuadGK")
Pkg.add("PyPlot")
using SpecialFunctions;
using QuadGK;
using PyPlot;
# Acceleration rate due to gravity in metres per second
# squared.
g=9.8
# Length of the pendulum in metres.
l=1.0

# Define our integrand
function f(y)
    # abs is used below to prevent complex number errors due to the sqrt
    return 1/sqrt(abs(2.0*g/l*sin(y)))
end

# Number of steps
N=1000000000;
# How close to theta=0 we start our integration and how
# close to theta=-pi we end our intgration.
# At theta=0,-pi our function becomes undefined, hence
# why we cannot start at exactly theta=0 or end at exactly
# theta=-pi.
tol=1/(25.0*N);
# Integration interval, [y0, yend]
y0=-tol;
yend=-pi+tol;
# Step size
h=(yend-y0)/N;
#
y=y0;

# Our integration function
function Simpson(h,y,i,N)
    if i == 1 || i == N+1
        return h/3*f(y)
    elseif (i % 2) == 1
        return 2*h/3*f(y)
    else
        return 4*h/3*f(y)
    end
end

t = 0.0;
# The actual integration
for i=1:N
    t = t + Simpson(h,y,i,N);
    y = y + h;
end
# Our QuadGK approximation to the integral
T=abs(quadgk(y -> f(y), 0, -pi)[1]);

# Difference between our QuadGK approximation and our 
# approximation using Simpson's method
error = abs(T + t)

```

(the `t = t + Simpson(h,y,i,N);` line is line 56). Any ideas why Julia doesn’t seem to understand that I _have_ defined t?

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 12, 2020, 10:47am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/2 "2020-06-12T10:47:42Z")

</div>

The content of a loop is a local scope, which does no have access to the global scope. The following should work, using `global`:

```julia
t = 0.0;
# The actual integration
for i=1:N
    global t
    t = t + Simpson(h,y,i,N);
    y = y + h;
end

```

The following works as well (notice that `tt` is defined outside the outer loop.

```julia
tt = 0
for j in 1:10
    for i in 1:10
        global tt
        tt += 1
    end
end

```

Within a function, `global` is not required. The loop will work fine.

```julia
function simpson()
    t = 0.0;
    # The actual integration
    for i=1:N   
       # `global` is not valid within a function
        t = t + Simpson(h,y,i,N);
        y = y + h;
    end
end

```

I do not know whether `global` refers just to the scope outside the loop, or to the function, or the entire global space.

---

<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: [June 12, 2020, 10:52am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/3 "2020-06-12T10:52:46Z")

</div>

@erlebach is entirely correct, just two points to add:

1. This behaviour will change in the next Julia version
2. More importantly, working in global scope is bad for performance as the compiler cannot guarantee the type of values used in the loop. It is highly recommended to wrap your code in functions, which would also get you around this problem. The simplest way to see this is to take your existing code and just wrap it in `function main() ... end`

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 12, 2020, 11:08am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/4 "2020-06-12T11:08:25Z")

</div>

@nilshg: I updated my message to include function as you were writing yours :-).

---

<div class="post-metadata">

### Author: ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)
#### Post date: [June 12, 2020, 11:51am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/5 "2020-06-12T11:51:15Z")

</div>

Your function code doesn’t work. It returns the error:

```julia
syntax: `global t`: t is a local variable in its enclosing scope

```

. Removing `global t` simply returns the error I started with.

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 12, 2020, 11:59am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/6 "2020-06-12T11:59:46Z")

</div>

I forgot to remove `global` from the function. It will work now. The `global` is only required if your loop is executed in the global scope.

---

<div class="post-metadata">

### Author: ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)
#### Post date: [June 12, 2020, 12:07pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/7 "2020-06-12T12:07:54Z")

</div>

I’m afraid, as I said in my last reply removing `global t` from the loop, even within your simpson() function just returns the original error. Namely, I executed this code in Julia:

```julia
# This script essentially finds the time taken for a
# simple pendulum that starts with zero velocity at the 
# positive x-axis to reach the negative x-axis (theta=-pi)
# using Simpson's rule
# t is time and y is theta
using Pkg;

Pkg.add("SpecialFunctions")
Pkg.add("QuadGK")
Pkg.add("PyPlot")
using SpecialFunctions;
using QuadGK;
using PyPlot;
# Acceleration rate due to gravity in metres per second
# squared.
g=9.8
# Length of the pendulum in metres.
l=1.0

# Define our integrand
function f(y)
    # abs is used below to prevent complex number errors due to the sqrt
    return 1/sqrt(abs(2.0*g/l*sin(y)))
end

# Number of steps
N=1000000000;
# How close to theta=0 we start our integration and how
# close to theta=-pi we end our intgration.
# At theta=0,-pi our function becomes undefined, hence
# why we cannot start at exactly theta=0 or end at exactly
# theta=-pi.
tol=1/(25.0*N);
# Integration interval, [y0, yend]
y0=-tol;
yend=-pi+tol;
# Step size
h=(yend-y0)/N;
#
y=y0;

# Our integration function
function Simpson(h,y,i,N)
    if i == 1 || i == N+1
        return h/3*f(y)
    elseif (i % 2) == 1
        return 2*h/3*f(y)
    else
        return 4*h/3*f(y)
    end
end

function simpson()
    t = 0.0;
    y = 0.0;
    # The actual integration
    for i=1:N
       # `global` is not valid within a function
        t = t + Simpson(h,y,i,N);
        y = y + h;
    end
end

simpson()
# Our QuadGK approximation to the integral
T=abs(quadgk(y -> f(y), 0, -pi)[1]);

# Difference between our QuadGK approximation and our 
# approximation using Simpson's method
error = abs(T + t)

```

and I received the error:

```julia
UndefVarError: t not defined

Stacktrace:
 [1] top-level scope at /data/GitHub/mine/math/julia-scripts/Simpson's_rule_pendulum_integral.jl:70
 [2] top-level scope at In[4]:1

```

---

<div class="post-metadata">

### Author: ![raphbacher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raphbacher/32/6019_2.png) [@raphbacher](https://discourse.julialang.org/u/raphbacher)
#### Post date: [June 12, 2020, 1:18pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/8 "2020-06-12T13:18:03Z")

</div>

Hi,  
The error is not happening at the same place : now that you have put your loop in a function, you have to return t from your function so that your `abs(T+t)` can know `t` (as `t` is now a local variable inside the simpson function scope.

---

<div class="post-metadata">

### Author: ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)
#### Post date: [June 12, 2020, 3:59pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/10 "2020-06-12T15:59:15Z")

</div>

Thanks, you’re right. I thought it was a different line, but I think I edited my script such that line 70 became `simpson()` and that lead to my thinking it was that loop that was still generating the error.

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 23, 2020, 11:29am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/11 "2020-06-23T11:29:12Z")

</div>

The following function does not work, contrary to my expectations:

```julia
function tst()
    for i in 1:10
        a = 3
    end
    print("a= ", a)
end

tst()

```

I get `a` is undefined!

```julia
tst()
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] tst() at ./none:5
 [2] top-level scope at none:0

```

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [June 23, 2020, 11:37am UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/12 "2020-06-23T11:37:18Z")

</div>

For that code to be legal, the compiler would have to determine that the loop body will run at least once. This is a hard problem in general, even though it would be simple in this particular case.

Put something like `a = 0` before the loop, and it will work.

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 23, 2020, 12:02pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/13 "2020-06-23T12:02:18Z")

</div>

Yes, I realized the trick, and use it. However, this implies that the behavior is different from what I thought.  
In Julia, one should never assume that loop variables are accessible from outside the loop context. Thank you.

---

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [June 23, 2020, 12:06pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/14 "2020-06-23T12:06:15Z")

</div>

While I realize this isn’t the “Julia Way”. I’ve found that always initializing my variables with `local` ensures that the variable is defined AND I know what context it’s in. i.e:

```julia
function tst()
    local a = 0
    for i in 1:10
        local b = 2
        a = 3
    end
    print("a= ", a)
end

tst()

```

---

<div class="post-metadata">

### Author: ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)
#### Post date: [June 23, 2020, 12:18pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/15 "2020-06-23T12:18:25Z")

</div>

I do not understand the need for `local b=0` in your example. What does `local` do exactly?

---

<div class="post-metadata">

### Author: ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)
#### Post date: [June 23, 2020, 12:49pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/16 "2020-06-23T12:49:08Z")

</div>

Says that the variable is local to “that” context, in this case the loop. I just added there as an example, it’s not being used.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 23, 2020, 12:50pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/17 "2020-06-23T12:50:42Z")

</div>

This question is very thoroughly answered in [the relevant section of the manual](https://docs.julialang.org/en/v1.4.2/manual/variables-and-scoping/#Local-Scope-1). I would recommend using it as your primary source to search for answers of questions about keywords of the language, as they surely will be fully explained in the manual.

---

<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: [June 23, 2020, 1:35pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/18 "2020-06-23T13:35:04Z")

</div>

Actually the `local` there is somewhat redundant:

```julia
function tst()
    a = 0
    # or this, if you do not need any specific initial value for a
    # local a
    for i in 1:10
        b = 2
        a = 3 + b
    end
    print("a= ", a)
end
tst()
julia> tst()
a= 5

```

Probably we should add that using `local b` inside the loop allows one to use the name `b` for a variable inside the loop which repeats the name of a variable in the outer scope:

```julia
julia> function tst()
           a = 0 ; b = 1
           for i in 1:10
               local b = 2
               a = 3 + b
           end
           print("a=",a," b=",b)
       end
tst (generic function with 1 method)

julia> tst()
a=5 b=1 # b is not changed in the loop

```

Although we should never do that, as the code might become a mess.

I think (not completely sure) that the fact that `b` is local to the scope of the loop allows for possible compiler optimizations which would not be possible otherwise. For instance, in my experience, some codes like this in Julia run faster than the almost equivalent translations of Fortran codes, and I this might be one of the explanations, because in Fortran you do not have that exclusive scope for variables in loops.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [June 23, 2020, 2:24pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/19 "2020-06-23T14:24:27Z")

</div>

> [@nilshg](#):
>
> This behaviour will change in the next Julia version

This is unexpected, I clearly missed something important. Could someone provide a link to some reading about this? Thanks in advance!

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [June 23, 2020, 2:28pm UTC](https://discourse.julialang.org/t/i-define-t-then-in-a-loop-im-told-its-undefined-why/41258/20 "2020-06-23T14:28:21Z")

</div>

Check out the first two bullet points in [https://github.com/JuliaLang/julia/blob/master/HISTORY.md#language-changes](https://github.com/JuliaLang/julia/blob/master/HISTORY.md#language-changes) (and the PRs and issues linked from there).
