# Local and global variables with the same name: ERROR: UndefVarError: x not defined

**URL:** https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951
**Category:** New to Julia
**Tags:** question
**Created:** [January 26, 2021, 5:11am UTC](https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951 "2021-01-26T05:11:19Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)
#### Post date: [January 26, 2021, 5:11am UTC](https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951/1 "2021-01-26T05:11:19Z")

</div>

In REPL

```julia
julia> x = randn(3);

julia> function add_one()
           x = x .+ 1
           @show x
       end
add_one (generic function with 1 method)

julia> add_one()
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] add_one() at .\REPL[2]:2
 [2] top-level scope at REPL[3]:1

```

- How to explain the above error?
- What should I do if I want to create a local variable with the same name as the global one (though it seems to be a bad practice)?

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [January 26, 2021, 5:20am UTC](https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951/2 "2021-01-26T05:20:24Z")

</div>

The issue is that when you write

```julia
x = x .+ 1

```

in your function, you are creating a new local variable with `x =`, so it ignores the “global” `x = randn(3)` you created outside, and then you are computing `x .+ 1` which assumes that `x` already exists.

You could do

```julia
x .= x .+ 1

```

and this will modify your outside `x`, or, better yet, also pass `x` as an argument and avoid any confusion:

```julia
function add_one!(x) # note x is an argument, and the ! indicates that this will mutate x
    x .= x .+ 1 # note the . in front of the assignment symbol =
    @show x
end

```

You could do something like `let x = x .+ 1` to assign a new `x` but I think that’d be confusing more than anything, since it really looks like you are trying to modify `x`.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [January 26, 2021, 6:03am UTC](https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951/3 "2021-01-26T06:03:34Z")

</div>

I think no amount of clarification / keywords can make the following fact not confusing to the reader:

> you have `x` on both left and right of `=` and one of them is local the other is global

* * *

I would imagine the least confusing syntax (doesn’t work in Julia right now) would be something like this:

```julia
x = global x .+ 1

```

or

```julia
local x = global x .+ 1

```

but it’s just, kinda annoying to look at with the length and information you need to process

---

<div class="post-metadata">

### Author: ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)
#### Post date: [January 26, 2021, 12:12pm UTC](https://discourse.julialang.org/t/local-and-global-variables-with-the-same-name-error-undefvarerror-x-not-defined/53951/4 "2021-01-26T12:12:25Z")

</div>

Within a scope, an identifier may be resolved either as local or as global.  
By default, if an identifier is encountered on the left-hand side of an assignment statement, its meaning is looked up in all enclosing scopes, excluding the global one (module scope), and a new binding is created if none is found. If an identifier only occurs in the right-hand sides of assignments, then it is searched for in all enclosing scopes, including the global one.

Here, you have the same identifier on both sides of an assignment. Then, the first rule takes precedence: `x` does not exist in any of the enclosing local scopes, so it is local, and we must evaluate the rhs of the statement and bind `x` to the result. But there is also `x` in the rhs, which is undefined, so there’s an error.

Now, what to do.  
a) It is perfectly fine to name local variables the same as globals, not needing to bother about the existence of a local name somewhere else in the program is one of the biggest virtues of scopes.  
b) If you want to create a _new_ variable `x` and use the global `x` in the same function, there’s `let` to help:

```julia
function add_one()
    let x_glob = x, x = x_glob .+ 1
        @show x
    end
end

```

The assignments in `let` are in nested scopes, so `x_glob = x` is evaluated in one scope, `x = x_glob .+ 1` in another, and there’s no clash.  
c) If you want to bind the global to another value, mark `x` as `global` anywhere in the function body:

```julia
function add_one()
    x = x .+ 1
    global x
    @show x
end

```

d) If you want to mutate a global, just use some mutating function on `x` as argument (like `x .= x .+ 1`, as suggested by @briochemc , because it is a syntactic sugar to `broadcast!`).
