# Global variables const by default?

**URL:** <https://discourse.julialang.org/t/global-variables-const-by-default/33138>\
**Category:** Internals & Design\
**Tags:** proposal\
**Created:** [January 9, 2020, 8:15am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138 "2020-01-09T08:15:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 9, 2020, 8:15am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/1 "2020-01-09T08:15:28Z")

</div>

Relatively poor performance resulting from the use of non-const global variables comes up quite often in Julia context. Wouldn’t it be better if variables were `const` by default? Or at least global variables. If a non-const global is really needed, one could write

```julia
julia> mutable x=3.14
3.14

julia> x="abc"
"abc"

```

but

```julia
julia> y=3.14
3.14

julia> y="abc"
ERROR: invalid redefinition of constant y
...

```

(This is of course not true output from present Julia 1.3.1)

Instead of `mutable` a different word could be used for variables, like `typemutable` which., however, seems a too long word.

The proposal would break existing code (perhaps a lot?). It is therefore aimed at a future major version upgrade of Julia.

---

<div class="post-metadata">

**Author:** ![Karajan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karajan/32/8545_2.png) [@Karajan](https://discourse.julialang.org/u/Karajan)\
**Post date:** [January 9, 2020, 8:45am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/2 "2020-01-09T08:45:38Z")

</div>

While it is a good goal to lessen performance problems, there are a few problems I can think of off the top of my head:

This makes writing scripts much more of a hassle. Right now you can write quick scripts (slow, in global scope) and high performance code (in functions etc.). With this proposal you make half of that more annoying, and I assume people will be up in arms

If you think I am exaggerating, maybe you have missed what happened the last time Julia became a little less global, when

```julia
julia> x = 1
1

julia> for i in 1:2
         x = i
       end

julia> x
1 <----

```

stopped working the way a lot of people expect it.

Besides, you can’t change a `const` without restarting Julia. If you, by accident, grabbed a good variable name like `x` without making it mutable, you are now stuck with that for the rest of your session. This happens to me pretty much every time I am overly eager to make my variables constant and change my mind later.

I think the benefits gained from this (people don’t have to be told to watch their globals the first time they run into this) doesn’t outweigh the hassle for everyone to mark their variables as mutable, when they want to hack together a quick script.

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 9, 2020, 9:21am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/3 "2020-01-09T09:21:21Z")

</div>

As far as I understand it the present `const` in Julia means that the type is constant, not the binding (or the value):

```julia
julia> const z=3.14
3.14

julia> z=1.0
WARNING: redefining constant z
1.0

```

The warning should in my opinion be removed. Present Julia has, unlike many other languages, no way to enforce that a variable does not change. This, I think, is fine. After all, linguistically the concept of a constant variable is contradictory.

I guess with this a large fraction of the “quick scripts” would still work as commonly expected, even if variables were “typeconstant” by default.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [January 9, 2020, 9:33am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/4 "2020-01-09T09:33:17Z")

</div>

`const` _does_ mean that the binding is constant:

```julia
julia> const foo = 3
3

julia> f() = foo
f (generic function with 1 method)

julia> f()
3

julia> foo = 4
WARNING: redefining constant foo
4

julia> f()
3

```

---

<div class="post-metadata">

**Author:** ![Karajan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karajan/32/8545_2.png) [@Karajan](https://discourse.julialang.org/u/Karajan)\
**Post date:** [January 9, 2020, 10:13am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/5 "2020-01-09T10:13:12Z")

</div>

> [@stephancb](#):
>
> I guess with this a large fraction of the “quick scripts” would still work as commonly expected, even if variables were “typeconstant” by default.

If you have hashed out everything then yes, this is true. However, I often have snippets like (copied from something I’m working on currently):

```julia
data = xf["Run1"]["A4:AU19"] # from an .xlsx file
data = data[2:end, 2:end] .|> float |> transpose

```

where I gradually change the type as I find out in what form I want to have the data. Of course this is getting cleaned up when I’m done but for exploration and messing around I find this quite convenient.

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 9, 2020, 10:40am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/6 "2020-01-09T10:40:21Z")

</div>

Perhaps my concept of “binding” is wrong, but in your code the binding of `foo` changed, and not the binding of `f()`. Continuing I got:

```julia
julia> f()=foo <--- new binding of function f
f (generic function with 1 method)

julia> f()
4

```

and then

```julia
julia> f=4
ERROR: invalid redefinition of constant f

```

So functions behave already like now proposed for variables: They can be rebound (without warning), but once a name is a function, it is always a function (until the end of the session).

---

<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:** [January 9, 2020, 10:51am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/7 "2020-01-09T10:51:11Z")

</div>

In most (library) code, globals are _not needed at all_. The best approach is not to make them constant, but to avoid global variables altogether.

At the same time, (nonconstant) globals are enormously useful for interactive work, so let’s keep them simple.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 9, 2020, 11:39am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/8 "2020-01-09T11:39:31Z")

</div>

> [@stephancb](#):
>
> Perhaps my concept of “binding” is wrong, but in your code the binding of `foo` changed, and not the binding of `f()` .

The fact that a warning is printed means that changing const bindings is not properly supported (otherwise, why show a warning?). It doesn’t error because it can save some annoyance in the REPL but you don’t really know what has cached that constant so it shouldn’t be used anywhere except when toying around in the REPL.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [January 9, 2020, 9:29pm UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/9 "2020-01-09T21:29:26Z")

</div>

To be clear this is a breaking change so can’t be considered, except in the context of “What should we be thinking about for Julia 2.0, some time years in the future.”

With that said, I am personally Pro that kinda discussion.  
So do continue

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 10, 2020, 10:20am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/10 "2020-01-10T10:20:33Z")

</div>

Yes, this would break both existing code and habits.

Probably it is difficult to say how much code this would break and how disturbing it would be for the work flow without actually trying it. However, unlike the example given by @Karajan , there would be no subtle bugs (“the value of variables magically changes”), but only firm errors. Automaticed code fixes throwing in `mutable`s seem possible.

I think that the proposal, to have variables type constant be default, but mutable binding, would overall harmonize the Julia language, i.e. variables then behave more similarly as already `struct`s and functions.

Another conclusion from the discussion so far might be that the meaning of `const` in Julia seems not obvious in the present version, constant type, constant binding etc? This could perhaps be addressed earlier than in some time years.

---

<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:** [January 10, 2020, 10:45am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/11 "2020-01-10T10:45:13Z")

</div>

> [@stephancb](#):
>
> the meaning of `const` in Julia seems not obvious in the present version, constant type, constant binding etc? This could perhaps be addressed earlier than in some time years.

As explained in its docstring (`?const`),

> In some cases changing the value of a const variable gives a warning instead of an error. However, this can produce unpredictable behavior or corrupt the state of your program, and so should be avoided. This feature is intended only for convenience during interactive use.

See the rest, it should be pretty clear. TL;DR: you are promising constant values, but may be allowed to change them with a warning.

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 10, 2020, 11:08am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/12 "2020-01-10T11:08:38Z")

</div>

Ok, thanks, this is clear.

---

<div class="post-metadata">

**Author:** ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)\
**Post date:** [January 11, 2020, 9:22am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/13 "2020-01-11T09:22:08Z")

</div>

This sounds like a good idea, but I actually think it is pretty problematic. Given Julia’s model, one wants to keep the REPL session open as long as possible, to avoid recompilation. If globals were const by default, one would tend to pollute the sessions top namespace with many const bindings that _cannot_ be removed without restarting. Imagine saying `a = 3` and getting an error because `a` was already a `String`, say, and having to traverse the alphabet looking for an unused name. Not nice.

EDIT: This already happens with names of functions and structs, of course, but these tend to be more verbose

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 13, 2020, 11:28am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/14 "2020-01-13T11:28:47Z")

</div>

One would have to remember to type `mutable a=3` (`mut<tab> a=3`) each first time in a session when a global for toying around in the REPL is declared. Personally I think, that I could get used to this.

With the proposal the performance of code translated from other languages (like Matlab) into Julia would not suffer when global variables are involved and not declared `const`. Right now such translated code seems frequently to be a source of disappointment.

---

<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:** [January 13, 2020, 11:55am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/15 "2020-01-13T11:55:18Z")

</div>

> [@stephancb](#):
>
> Right now such translated code seems frequently to be a source of disappointment.

Making globals constant is _not_ the right solution to the performance problem caused by non-constant globals.

Overusing globals (which, in most cases, using _any_) is simply bad style in Julia, and most modern languages. It makes it very difficult to reason about code, precludes various compiler optimizations (even for constant type containers).

Instead of encouraging it, one should _avoid_ direct translation of code that uses globals for nontrivial computations (ie anything with flow control) in non-exploratory code.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [February 5, 2020, 8:29pm UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/16 "2020-02-05T20:29:01Z")

</div>

What about raising a PerformanceWarning if non-constant globals are used inside a function?  
This would give the programmer a clear indication that this is not good (not only for performance reasons). On the other hand, it would not prevent usage of globals while hacking in the REPL.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [February 5, 2020, 8:52pm UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/17 "2020-02-05T20:52:18Z")

</div>

> [@lungben](#):
>
> What about raising a PerformanceWarning if non-constant globals are used inside a function?

This is what [Traceur.jl](https://github.com/JunoLab/Traceur.jl) does.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 6, 2020, 11:53pm UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/18 "2020-02-06T23:53:46Z")

</div>

In most posts where the OP is seeing worse than expected performance, it is clear that the OP has not read any of the numerous other threads on the topic on this forum, neither the performance tips in the manual. Changing the language to accommodate this kind of user is probably not the right way to go about it, actually, a discourse bot could probably identify and prompt such users already while the post is being written, to read the performance tips before posting.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [February 8, 2020, 10:12am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/19 "2020-02-08T10:12:38Z")

</div>

Thanks for pointing this out, looks very useful, I’ll take a closer look.

However, I think for beginners (who probably neither know Traceur nor `@code_warntype` yet) such a PerformaceWarning would be useful.  
Especially if people do benchmarking of various languages (without being deep into all of them), this could give misleading results.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 8, 2020, 10:15am UTC](https://discourse.julialang.org/t/global-variables-const-by-default/33138/20 "2020-02-08T10:15:21Z")

</div>

The warning could also be very annoying to those who are aware of the problem but choose to program in a certain way for other reasons. Also to be fair, both these tools are listed in the manual so beginners who take the time to read the manual will know about them. Beginners who do not take the time to read the manual perhaps can’t expect to achieve maximum performance?

[Next page](https://discourse.julialang.org/t/global-variables-const-by-default/33138.md?page=2)
