# 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:** 11\
**Page:** 2

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

</div>

> [@erlebach](#):
>
> would be less efficient, since the type of a could change and the compiler has to take that into account.

No, not at all. With few exceptions, the function signature has no effect on the performance of the code within that function.

---

<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 13, 2020, 4:28pm UTC](https://discourse.julialang.org/t/const-variables/42956/22 "2020-07-13T16:28:36Z")

</div>

> [@erlebach](#):
>
> ```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.

No, it’s not like that. Julia does just-in-time (JIT) complilation. This means that the compilation of functions does not happen when you define them, but when you run them. And when you run `anyfunc(a)`, the type of `a` is always known!

So, in your first example:

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

```

that won’t be compiled until it is called for the first time. It’s exactly the same with:

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

```

The difference is that in this second version, if you do `anyfunc(1.0)` it will compile a new, different code for `Float64` arguments, while in the first version it will throw an error – unless you defined a different method that allows that type.

In general, performance is more affected by the code _inside_ the function (e.g. ensuring [type stability](https://docs.julialang.org/en/v1/manual/faq/#man-type-stability-1)) than by the prior knowledge of the arguments types.

---

<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, 5:08pm UTC](https://discourse.julialang.org/t/const-variables/42956/23 "2020-07-13T17:08:51Z")

</div>

> [@erlebach](#):
>
> since the type of a could change and the compiler has to take that into account

In addition to the excellent answers by others: I think you misunderstand how Julia’s compilation model works, which will make it difficult to write performant code. I would recommend reading the whole of

[https://docs.julialang.org/en/v1/manual/performance-tips/](https://docs.julialang.org/en/v1/manual/performance-tips/)

and then

[![](https://global.discourse-cdn.com/julialang/original/3X/9/c/9c7dcad2631cec7ff3a22f67682c60b013a07c63.jpeg "JuliaCon 2017 | AoT or JIT: How Does Julia Work? | Jameson Nash") ](https://www.youtube.com/watch?v=7KGZ_9D_DbI)

IMO it is really worth investing in this.

---

<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, 5:21pm UTC](https://discourse.julialang.org/t/const-variables/42956/24 "2020-07-13T17:21:10Z")

</div>

Thank you, Tamas! I will certainly do so. My codes are already very performant, but one can always improve.  
At the moment, I work completely within functions, do pre-allocation, use the “.” operator as needed, etc, all based on discourse discussions and reading documentation. But of course, there is understanding and there is grokking.  
I do agree that I do not have a good understanding of how compilation work in Julia, but I do understand lazy compiling, late binding, etc  
I will return …

---

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

</div>

> [@Henrique\_Becker](#):
>
> Specially for parameters. Just use a Dict, or create your own struct and pass it along

I have not tested it yet, but I think that Dicts for parameters are slower than (concretely typed) structs:

1. For each Dict access, the key needs to be hashed and a lookup performed. Lookups of values in structs should be much faster.
2. If you have multiple parameter types, the Dict will no longer have a concrete value type (worst case Any), thus the type of any elements in this Dict cannot be determined at Compile-time anymore.

---

<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, 6:20pm UTC](https://discourse.julialang.org/t/const-variables/42956/26 "2020-07-13T18:20:44Z")

</div>

“2. If you have multiple parameter types, the Dict will no longer have a concrete value type (worst case Any), thus the type of any elements in this `Dict` cannot be determined at Compile-time anymore.”

In that case, one solution is to have multiple dictionaries, one for each type. But it is still not fully clear.  
If the function accesses specific elements of the dictionary in the function, wouldn’t the compiler know the types?  
If access to the variables were via a loop, then the knowledge is lost. Ultimately, it is all about the level of sophistication of the compiler. I recognize that these issues can be quite difficult.

```julia

param = Dict(:a => 2.3, :b => 5)

function tst(p)
a = p[:a]
b = p[:b]
end

tst(param)

```

Doesn’t the compiler know the types of the variables `a` and `b`?

---

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

</div>

> [@erlebach](#):
>
> Doesn’t the compiler know the types of the variables `a` and `b` ?

No. `p` is a `Dict{Symbol, Real}`, so the compiler can only assume that `a` and `b` are both some subtype of the abstract type `Real`. This is easy to check for yourself:

```julia
julia> @code_warntype tst(param)
Variables
  #self#::Core.Compiler.Const(tst, false)
  p::Dict{Symbol,Real}
  a::Real
  b::Real

Body::Real
1 ─ (a = Base.getindex(p, :a))
│ %2 = Base.getindex(p, :b)::Real
│ (b = %2)
└── return %2

```

Given the entire program as you’ve written it, a hypothetical compiler _could_ perform enough constant propagation to turn your entire code into `return 5`, but the compiler we actually have isn’t going to do that for you.

---

<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, 6:33pm UTC](https://discourse.julialang.org/t/const-variables/42956/28 "2020-07-13T18:33:15Z")

</div>

Got it. Thanks! It does all make sense.

Gordon

---

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

</div>

```julia
Base.@kwdef

```

is really useful for the definition of parameter structures, it allows to define default values directly in the structure definition.

---

<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, 10:57pm UTC](https://discourse.julialang.org/t/const-variables/42956/30 "2020-07-13T22:57:41Z")

</div>

Sorry, my home lost electricity for the last eight hours. When I said:

> This is a little crude, but why do you not just gives every method a last parameter called `params` […]

I meant that my suggestion was a little crude, because it was vague and did not point the difference between each option. I was not referring to your comment.

I worry a little about your example:

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

```

Seems like you think that there is a connection between the global variable `a` and the parameter `a`, the two of them only share the same name (and therefore, when you reference `a` in your function it will always refer to the parameter, not the global variable), but they are two completely distinct things. They only become the same thing if you call `anyfunc` passing as parameter the global `a`.

> [@lungben](#):
>
> I have not tested it yet, but I think that Dicts for parameters are slower than (concretely typed) structs:

Yes. I am absolutely sure of it. However, in an prototype phase, it can be more convenient to use a `Dict` and do not worry about adding and removing fields (and changing the construction of the object) each time something changes. I was just suggesting things that work, with different degrees of flexibility and performance. I use a `Dict` myself, because I get it from the argument parser, and the performance of accessing the parameters is completely irrelevant in my case (the code takes minutes to hours, most time from Gurobi solver, the access to parameters do not account for 0.01% of the total time, probably orders of magnitude less).

> [@erlebach](#):
>
> If the function accesses specific elements of the dictionary in the function, wouldn’t the compiler know the types?

As already answered this is not guaranteed. However, if you use a `Dict` you should probably never access a parameter repeatedly inside a loop, but instead do: `param_name :: TypeOfParam = params_dict[:param_name]` before such heavy use of the parameter. As I said above, use a `Dict` only if the convenience matters more, and you do not have to use a lot of the parameters each iteration of tight loops (you can unpack all values as I suggested above but at this point is probably better to just use an immutable `struct` and access the fields directly).

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [February 7, 2022, 2:36pm UTC](https://discourse.julialang.org/t/const-variables/42956/31 "2022-02-07T14:36:08Z")

</div>

Split this topic on February 7, 2022, 2:36pm UTC

6 posts were split to a new topic: [Typeconst proposal](https://discourse.julialang.org/t/typeconst-proposal/75953)

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