# Const variables

**URL:** <https://discourse.julialang.org/t/const-variables/42956>\
**Category:** New to Julia\
**Tags:** constants\
**Created:** [July 12, 2020, 5:40pm UTC](https://discourse.julialang.org/t/const-variables/42956 "2020-07-12T17:40:58Z")\
**Posts on this page:** 20\
**Page:** 1

<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:** [July 12, 2020, 5:40pm UTC](https://discourse.julialang.org/t/const-variables/42956/1 "2020-07-12T17:40:58Z")

</div>

I am sure this issue has been debated before.  
By now, I have learned that all global variables must be constants. But I am less clear on global variables that are a function of other global variables, already defined as `const`. For example:

```julia
const var1 = 3
var2= 3 * var1

```

Must `var2` be defined as `const` to get the maximum efficiency if `var1` is used within a function? I would think not since its type is known to the compiler.

Thank you for any input.

---

<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:** [July 12, 2020, 5:51pm UTC](https://discourse.julialang.org/t/const-variables/42956/2 "2020-07-12T17:51:40Z")

</div>

There’s nothing as “global variables that are a function of other global variables”. If `var1` and `var2` are both globals they are just that, there’s nothing that links the two.

Also, it’s not right to say “all global variables must be constants”. There are many good use of non-const globals. Just be careful if you want to use them where performance matters a lot.

---

<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:** [July 12, 2020, 8:25pm UTC](https://discourse.julialang.org/t/const-variables/42956/3 "2020-07-12T20:25:37Z")

</div>

Yes you should make `var2` const as well if you want performance.

But ideally parameters should just be passed to each function that needs them.  
If there are several then they can just be wrapped into a `struct`.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [July 12, 2020, 9:26pm UTC](https://discourse.julialang.org/t/const-variables/42956/4 "2020-07-12T21:26:49Z")

</div>

To expand on the previous answers:

Remember that in Julia the variables are only names bound to objects, not memory allocations, etc. When you declare a variable as `const`, you are just telling something about how that name shall be used.

So, it doesn’t matter what content you assign to `var2` the first time. If you don’t declare it as `const`, there is nothing stopping you from assigning it a different value – maybe of a different type – later on.

---

<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:** [July 13, 2020, 1:10am UTC](https://discourse.julialang.org/t/const-variables/42956/5 "2020-07-13T01:10:56Z")

</div>

Complementing even more what @heliosdrm said. Why you think `var2` has its type know by the compiler, but `var1` has not? Clearly, `var2` can only have the type known if `var1` has its type known.

Also, if `var2` is not `const`, it can be changed completely at any moment, there is nothing making that its value must be always related to `var1`, if you need a global variable that changes accordingly every time some other global variable changes its value, then what you want is a function that computes some formula using global variables already available, and not a new global variable.

---

<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:** [July 13, 2020, 1:28am UTC](https://discourse.julialang.org/t/const-variables/42956/6 "2020-07-13T01:28:10Z")

</div>

> [@Henrique\_Becker](#):
>
> but `var1` has not?

Not sure I follow. The type of var 1 is known: it is an integer, in this case. It can change. In my example, `var2` is of type integer as well (i.e., the same type as `var1`. But as was already mentioned, after compilation, I could change the type of either variable, and the compiler must allow for that, thus decreasing efficiency.

The word `const` is really a misnomer. It is not that the variable is constant. It is the variable type that is constant, which is quite different. If I write

```julia
const a = 3::Int64

```

I am allowed to change the value of `a` without impacting the efficiency of the compiler, but I cannot change the type of `a`.

I thank you all for deepening my understanding. I will mark this problem solved, but please continue to write!

---

<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:** [July 13, 2020, 1:33am UTC](https://discourse.julialang.org/t/const-variables/42956/7 "2020-07-13T01:33:44Z")

</div>

Here is an example of why (1) global variables are bad, and (2) changing `const` variables does not do what one might expect:

```julia
julia> const a = 3
3

julia> f(x) = a * x
f (generic function with 1 method)

julia> f(10)
30

julia> a = 4
WARNING: redefinition of constant a. This may fail, cause incorrect answers, or produce other errors.
4

julia> f(10)
30

```

---

<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:** [July 13, 2020, 1:36am UTC](https://discourse.julialang.org/t/const-variables/42956/8 "2020-07-13T01:36:29Z")

</div>

Ok, I have to study that. I do note that you have not recompiled the function. But this also means that if I use a function in a precompiled library and use a constant as one of its argument, I will get the wrong result when changing its value.

What happens if I defined instead a `struct`?

```julia
struct A
   a::Int64
end

```

and perform the same experiment. I will have to try some things out.

---

<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:** [July 13, 2020, 1:41am UTC](https://discourse.julialang.org/t/const-variables/42956/9 "2020-07-13T01:41:19Z")

</div>

You still need to make an instance of that struct, which will presumably be a global variable, and you’re back to the same issue.

A simple solution is to make your “global variables” functions:

```julia
julia> f(x) = aa() * x
f (generic function with 1 method)

julia> f(10)
30

julia> aa() = 4
aa (generic function with 1 method)

julia> f(10)
40

```

The best solution is to just make `f` take `a` as an argument:

```julia
julia> aaa = 3
3

julia> f(aaa, 10)
30

julia> aaa = 4
4

julia> f(aaa, 10)
40

```

It’s so much easier to understand what’s going on now!

EDIT: Forgot to include the definition of `f` with two arguments:

```julia
f(a, x) = a * x

```

---

<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:** [July 13, 2020, 1:43am UTC](https://discourse.julialang.org/t/const-variables/42956/10 "2020-07-13T01:43:32Z")

</div>

I just tried your example and was not able to reproduce your results. I tried this in REPL. I will now do so using the console.

```julia
@show const bb = 3
tst2(x) = 3*x
@show tst2(bb)
@show bb = 10
@show tst2(bb)

```

Here is the output, which behaves as I would expect, but differently than what you showed:

```julia
const bb = 3 = 3
tst2(bb) = 9
WARNING: redefining constant bb
bb = 10 = 10
tst2(bb) = 30

```

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [July 13, 2020, 1:57am UTC](https://discourse.julialang.org/t/const-variables/42956/11 "2020-07-13T01:57:42Z")

</div>

It behaves the same as he showed.  
The `bb` in the function remains equal to `3`. (EDIT: Sorry, as said below, there wasn’t even a `bb` in the function, it was hardcoded to 3.)

The one you use as an argument is updated.

> Not sure I follow. The type of var 1 is known: it is an integer, in this case. It can change. In my example, `var2` is of type integer as well (i.e., the same type as `var1` . But as was already mentioned, after compilation, I could change the type of either variable, and the compiler must allow for that, thus decreasing efficiency.

You cannot change the type of a `const`.

```julia
julia> const V1 = 3
3

julia> const V1 = 5
WARNING: redefinition of constant V1. This may fail, cause incorrect answers, or produce other errors.
5

julia> const V1 = 5.0
ERROR: invalid redefinition of constant V1
Stacktrace:
 [1] top-level scope
   @ REPL[12]:1

To edit a specific method, type the corresponding number into the REPL and press Ctrl+Q

```

---

<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:** [July 13, 2020, 2:08am UTC](https://discourse.julialang.org/t/const-variables/42956/12 "2020-07-13T02:08:39Z")

</div>

You didn’t include the global variable in the _definition_ of `tst2`.

---

<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:** [July 13, 2020, 2:19am UTC](https://discourse.julialang.org/t/const-variables/42956/13 "2020-07-13T02:19:15Z")

</div>

I am sure @dpsanders is much more knowledgeable than I am, but I find necessary to point that

> The word `const` is really a misnomer. It is not that the variable is constant. It is the variable type that is constant, which is quite different.

Is just completely wrong. The **binding** is constant, not the _type_. What difference this make? Exactly what @dpsanders pointed out, but trying to explain more exhaustively I would say: if the binding `var1` is constant, then you cannot assign a new value/object for `var1` (_even of the same type_), you can change a mutable field inside that value, but you cannot ever replace the _entire_ object inside `var1` by another.

This is: if `tmp1` is an array, then you can add, remove, and replace elements; but you cannot never replace the original array by a brand new array (for example, to “empty” the array temporarily while keeping the old array in an auxiliary variable, with the intent of putting it back after, without having to make any copies, a `swap` basically); it is not the type that is fixed, it is that initial object (which can have mutable fields) that is fixed there forever. If it is an `Int` like in your example, this means you cannot never change that value (because an `Int` has no mutable fields inside it you can change). That name will point to the same ‘memory position’/reference/value its entire existence.

---

<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:** [July 13, 2020, 2:41am UTC](https://discourse.julialang.org/t/const-variables/42956/14 "2020-07-13T02:41:32Z")

</div>

I admit I am a beginner in Julia, which is why I am posting. Consider my duplication of the example provided by @dpsanders :

```julia
julia> const cc = 3
3

julia> const cc =5
WARNING: redefining constant cc
5
WARNING: redefining constant zzz

```

Note that the printout is different and my constant changed. I am using Julia 1.4.0-rc1.0. His example is copied from his message above (what version are you using, @dpsanders?)

```julia
julia> const V1 = 3
3

julia> const V1 = 5
WARNING: redefinition of constant V1. This may fail, cause incorrect answers, or produce other errors.
5

julia> const V1 = 5.0
ERROR: invalid redefinition of constant V1
Stacktrace:
 [1] top-level scope
   @ REPL[12]:1

To edit a specific method, type the corresponding number into the REPL and press Ctrl+Q

```

---

<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:** [July 13, 2020, 12:47pm UTC](https://discourse.julialang.org/t/const-variables/42956/15 "2020-07-13T12:47:54Z")

</div>

This is just a convenience to be used in the REPL instead of re-starting it. If you check the [manual section on constants](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Constants-1) you will find:

> Note that although sometimes possible, changing the value of a `const` variable is strongly discouraged, and is intended only for convenience during interactive use. Changing constants can cause various problems or unexpected behaviors. For instance, if a method references a constant and is already compiled before the constant is changed then it might keep using the old value: […]

In other words, the documentation gives no guarantee that it will work, and if it works there may be hidden problems. I really would have preferred that the behavior was just always throwing an error, as this ends up causing more headaches than just having to re-start the REPL, if someone does this without reading the manual.

---

<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:** [July 13, 2020, 1:01pm UTC](https://discourse.julialang.org/t/const-variables/42956/16 "2020-07-13T13:01:48Z")

</div>

Thank you. So the bottom line seems to be (as I have read in several places):  
(this does make a greater impact when one is actually programming as opposed to simply reading.)

1. do not use globals
2. if you use globals, the preference is not to use const
3. if efficiency is the desired outcome, use structs to store any global parameters
4. the preference is to use immutable structs for maximum efficiency.
5. Minimize the number of parameters defined outside a function.

So my remaining question is: if I use a struct, and initialize a structure in the global space, must I make it a const for maximum efficiency? Initializing in the global space is the only solution UNLESS one uses command-line arguments or inputs data from an input file (which is likely the best and more flexible approaches).

Did I miss anything important?

Thank you, again.

---

<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:** [July 13, 2020, 1:49pm UTC](https://discourse.julialang.org/t/const-variables/42956/17 "2020-07-13T13:49:26Z")

</div>

About your list, well, let me give you my more nuanced (and incredibly verbose) vision:

1. Avoid globals. Specially for parameters. Just use a Dict, or create your own struct and pass it along (there some package solutions too). I use globals. I have a global timer in my module, so I can reset it, run a bunch of my methods, and then get how much was spent in each method (and each method called inside them). It is the best solution? No. But it is good enough and used only for debug, not for anything that will get in a paper.
2. Considering that you will use globals. If you may need to change the entire object including its type: do not use `const` (and take the performance hit). If the type never changes, but you may need to change the whole object, not just a field, then use something like `const var = Ref(10)` for storing an `Int`, this creates a `const` binding to a reference (you need to use `[]` to access, or set, the `Int` value), so you get type-stability and gets to change the value safely. If you have a lot of these globals (type-fixed but with an object that may need to be wholly replaced), then instead of using `Ref` you may also declare your own mutable struct and use it with `const` and without the `Ref` (because the fields are mutable and can be changed safely). If you are completely sure you will never need to replace the entire object but only mutate a fields of it (or call mutating methods over it), then you use `const` (directly over the value, not wrapping inside a Ref).
3. I do not think the main point of using `structs` is efficiency, but just that you are following (1) by doing this. Unless you are talking about using a global struct to store the values, I have addressed this in the point above. Basically, if `const` was used (one way or another) then the performance of the global variable will not be so much different from the passed-along parameters (but I welcome someone showing me wrong).
4. If you have a grouping of fields that never change (or change very rarely), or they change but almost all fields in the same point (so it is almost the same cost of creating the struct again), then immutable structs are a good idea. If you need to consistently change the values of single fields, not so good. If you actually have a loop that needs to change a single field in that structure multiple times, then surely use a mutable struct.
5. Yes. This is basically (1) again.

I addressed your question about structs and global space in (2) I think.

I am not sure if I understand the “is the only solution UNLESS” bit. This is a little crude, but why do you not just gives every method a last parameter called `params` that is either a `Dict`, a `NamedTuple`, or your own `struct` and each method pass it along for the methods it calls? Then you can have a main function like:

```julia

function main()
    # initialize your struct/dict/tuple here
    params = ...
    # call your method with such params
    my_method(..., params)
end

main()

```

And instead of changing global variables change the definition of `params`.

---

<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:** [July 13, 2020, 1:51pm UTC](https://discourse.julialang.org/t/const-variables/42956/18 "2020-07-13T13:51:27Z")

</div>

> [@erlebach](#):
>
> if you use globals, the preference is not to use const

This really depends on your application. If the value is actually a constant, use `const`. If you want a mutable container, also use `const`.

> [@erlebach](#):
>
> the preference is to use immutable structs for maximum efficiency

Again, if you need `mutable struct` because you change those values, that is fine too.

> [@erlebach](#):
>
> Initializing in the global space is the only solution UNLESS one uses command-line arguments or inputs data from an input file

If the function gets the value as a _parameter_, then it does not matter. Eg like this:

```julia
function foo(parameters)
    ...
end

par = parse_from_args(ARGS)
foo(par)

```

---

<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:** [July 13, 2020, 2:49pm UTC](https://discourse.julialang.org/t/const-variables/42956/19 "2020-07-13T14:49:00Z")

</div>

Great answer!!! Yes, my answer was very crude in comparison. I will perhaps perform some experiments. My preference is not to use goals. Passing known types via function arguments is my preference.

Thanks again! I hope this helps others. I have nothing to add.

Gordon

---

<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:** [July 13, 2020, 4:01pm UTC](https://discourse.julialang.org/t/const-variables/42956/20 "2020-07-13T16:01:46Z")

</div>

> [@Tamas\_Papp](#):
>
> If the function gets the value as a _parameter_ , then it does not matter.

That is good to know! However, wouldn’t that only be true if the parameter values had specified types? For example:

```julia
a = 35

function anyfunc(a::Int64)
   ...
end

```

would be as efficient as using `const a` since the function knows the type of its argument. However,

```julia
a = 35
function anyfunc(a)
...
end

```

would be less efficient, since the type of a could change and the compiler has to take that into account. Whatever the answer, I assume that the more information is known to the compiler, the higher likelihood of improved efficiency.

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