# Julia doesn't catch undefined variables at compile time?

**URL:** <https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616>\
**Category:** General Usage\
**Created:** [March 12, 2017, 5:55am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616 "2017-03-12T05:55:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [March 12, 2017, 5:55am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/1 "2017-03-12T05:55:34Z")

</div>

```julia
function foo()
    x = 1
    if x < 1
        println("less than 1")
        println(bar)
    else
        println("greater than or equal to 1")
    end
end

foo()

```

the result is

greater than or equal to 1

unless of course you set x=0 then you get

less than 1  
ERROR: LoadError: UndefVarError: bar not defined  
in foo() at /home/nfs4/briand/src/julia/jcap/test.jl:5  
in include\_from\_node1(::String) at ./loading.jl:488  
in process\_options(::Base.JLOptions) at ./client.jl:262  
in \_start() at ./client.jl:318  
while loading /home/nfs4/briand/src/julia/jcap/test.jl, in expression starting on line 11

is there a magic switch to make the compiler try harder?  
you can’t write robust code if you actually have to wait for that if clause to actually execute before catching that error.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 12, 2017, 6:27am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/2 "2017-03-12T06:27:29Z")

</div>

This is not possible, since there could be a global variable `bar` that is defined after you define `foo`, but before you call it:

```julia
julia v0.5> function foo()
                x = 0
                if x < 1
                    println("less than 1")
                    println(bar)
                else
                    println("greater than or equal to 1")
                end
            end
foo (generic function with 1 method)

julia v0.5> bar = 3
3

julia v0.5> foo()
less than 1
3

```

EDIT: However, just use `Lint.jl` or install the `linter-julia` package in Atom and you will immediately be told that you are using an undeclared symbol.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 12, 2017, 7:11am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/3 "2017-03-12T07:11:53Z")

</div>

> [@dpsanders](#):
>
> This is not possible, since there could be a global variable bar that is defined after you define foo, but before you call it

You are of course right, but a warning could be useful. I think that mistakenly using a variable one forgot to initialize (or mistyping a variable name) is much more common in practice.

---

<div class="post-metadata">

**Author:** ![purplishrock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/purplishrock/32/13451_2.png) [@purplishrock](https://discourse.julialang.org/u/purplishrock)\
**Post date:** [March 12, 2017, 7:13am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/4 "2017-03-12T07:13:59Z")

</div>

ouch.

Would it be too bold to request a global variable declaration of some sort??

The compiler proper should really be able to catch this sort of thing.

allowing unfettered/unidentified use of global is really problematic.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 12, 2017, 7:35am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/5 "2017-03-12T07:35:53Z")

</div>

There is sort of a global variable declaration:

`global a`

means that `a` inside the function refers to a global variable of that name.

Maybe it could be enforced that it would be an error to _not_ do this, but equally likely there are problems with that that I’m not aware of.

As I added as an edit to my original post, this is the kind of thing that a linter finds easily.  
Try the linter-julia atom package – it’s very neat.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 12, 2017, 12:53pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/6 "2017-03-12T12:53:45Z")

</div>

> [@dpsanders](#):
>
> Maybe it could be enforced that it would be an error to not do this

This will turn the original function into this:

```julia
function foo()
    global println
    x = 0
    if x < 1
        println("less than 1")
        println(bar)
    else
        println("greater than or equal to 1")
    end
end

```

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 12, 2017, 2:22pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/7 "2017-03-12T14:22:35Z")

</div>

Isn’t there a way that only variables and not functions requires a global declaration ? In my experience Julia’s implicit assumption that everything is global can lead to some hard-to-find bugs and performance issues.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 12, 2017, 2:25pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/8 "2017-03-12T14:25:33Z")

</div>

I think @yuyichao’s point is that there is no way to distinguish function names from other variables. E.g. bar could just as easily be the name of a function defined elsewhere.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 12, 2017, 2:37pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/9 "2017-03-12T14:37:57Z")

</div>

I guess you could get function calls at parse time but if you use a function in map or such, it wouldn’t work, so you would still need to declare those as global.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 12, 2017, 2:43pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/10 "2017-03-12T14:43:29Z")

</div>

No, for the same reason as I gave in my first post: the function bar may be defined after foo.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 12, 2017, 3:04pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/11 "2017-03-12T15:04:31Z")

</div>

In my understanding OP’s point is that it shouldn’t be allowed and that it should throw an error at parse time if you don’t declare bar as global.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [March 12, 2017, 3:21pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/12 "2017-03-12T15:21:08Z")

</div>

Right, but @yuyichao’s point was that then you would have to declare as global any function that you used inside a given function.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 12, 2017, 3:41pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/13 "2017-03-12T15:41:44Z")

</div>

But since function calls are parsed as such you might not need to for normal function calls, so

```julia
function foo()
    println("less than 1")
end

```

would be valid, but not

```julia
function foo()
    map(println,["less than 1"])
end

```

Which would need to be written as

```julia
function foo()
    global println
    map(println,["less than 1"])
end

```

It would still be bad, but not as bad.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 12, 2017, 3:52pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/14 "2017-03-12T15:52:21Z")

</div>

There’s not really anything special about function calls. There’s also (constant) globals (used a lot in basically every packages that uses `ccall`) and many functions are used as variables now that we support broadcast syntax.

A better version of this would be requiring pre-declaration of globals in the global scope so at least they only needs to be declared once and only for recursive once that can’t be taken care of by reordering.

There’re still corner cases though. There’s `eval` and generated function where you basically can’t do this at all (you can’t know at parse time what symbols they are using). And `using` also complicate things a bit so someone wanting this feature would need to come up with a semantic that’s compatible with all these. In the mean time, I believe a linter can easily warn about this (and I’m pretty sure Lint.jl can do that already).

---

<div class="post-metadata">

**Author:** ![jballanc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jballanc/32/328_2.png) [@jballanc](https://discourse.julialang.org/u/jballanc)\
**Post date:** [March 12, 2017, 5:58pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/15 "2017-03-12T17:58:28Z")

</div>

For what it’s worth, Clojure solves this issue with a `declare` macro that does forward declaration of identifiers. I think Clojure has much of the same issues to deal with as Julia (i.e. `eval`, macros, symbols imported from other namespaces), so I see no reason why it isn’t doable.

I think it’s more an issue of taste. As has been pointed out, doing late resolution of identifiers enables one to reference globals, or even functions, that will be declared later. This is particularly useful when working at the REPL. It also allows one to organize code in a file more freely.

Because of Clojure’s eager resolution, and because `declare` is seen as a tool only to break issues of mutual reference, what ends up happening is that Clojure source files are peppered with simple helper methods toward the top, while the “meat” of a namespace is usually located near the bottom of the file.

The flip side, of course, is being more secure that you haven’t made a typo somewhere, but if that’s really all you need then I agree that a linter is more useful than changing such a fundamental bit of the language.

---

<div class="post-metadata">

**Author:** ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)\
**Post date:** [March 13, 2017, 3:57am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/16 "2017-03-13T03:57:14Z")

</div>

Julia will happily compile all kinds of meaningless or nonsensical code like 6+“a” – not just undefined variables – without an error message at compile time. Only when the code executes will the error be issued. For this reason, I suggest that you develop a suite of test cases and use them in conjunction with a code-coverage tool for any Julia project of significance. This is not just Julia advice, however. Even in a language like C++ in which all variables have to be declared and all function calls have to make sense at compile time, it is still a good idea to check code coverage on a project of significance.

---

<div class="post-metadata">

**Author:** ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)\
**Post date:** [March 13, 2017, 10:39am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/17 "2017-03-13T10:39:16Z")

</div>

I’m wondering if the `global` could be required just for non-`const` globals? It seems to me that these are the ones that cause the majority of the problems (they often come from typo’s, they cause type stability issues, etc).

A warning emitted at specialization time would seem reasonable if an unmarked, non-`const` global is to be searched for at run time.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 13, 2017, 11:35am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/18 "2017-03-13T11:35:12Z")

</div>

Specialization/compile time would be the worst time for such a warning. It’s indeterministic and won’t help static checking.

---

<div class="post-metadata">

**Author:** ![pint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pint/32/125_2.png) [@pint](https://discourse.julialang.org/u/pint)\
**Post date:** [March 13, 2017, 11:58am UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/19 "2017-03-13T11:58:19Z")

</div>

maybe the whole thing is best addressed by a reasonably smart syntax highlighter in the editor? if there would be a slightly different color to local symbols vs outer symbols, you would immediately notice that it is not what you wanted. and it is not a problem if functions are colored as outer, since they actually are.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [March 13, 2017, 12:52pm UTC](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616/20 "2017-03-13T12:52:20Z")

</div>

Related

[https://github.com/JuliaLang/julia/issues/14959](https://github.com/JuliaLang/julia/issues/14959)

[Next page](https://discourse.julialang.org/t/julia-doesnt-catch-undefined-variables-at-compile-time/2616.md?page=2)
