# Julia 1.7 and below do not have constant-type globals. Julia 1.8 implemented typed globals

**URL:** <https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989>\
**Category:** General Usage\
**Tags:** question\
**Created:** [February 8, 2017, 8:37pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989 "2017-02-08T20:37:19Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [February 8, 2017, 8:37pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/1 "2017-02-08T20:37:19Z")

</div>

Quoting the documentation ([http://docs.julialang.org/en/latest/manual/types.html#Type-Declarations-1](http://docs.julialang.org/en/latest/manual/types.html#Type-Declarations-1)):

> Currently, type declarations cannot be used in global scope, e.g. in the REPL, since Julia does not yet have constant-type globals.

Why? Are there plans to support global type declarations some day?

---

<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:** [February 8, 2017, 8:54pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/2 "2017-02-08T20:54:12Z")

</div>

You can do that pretty easily with a constant mutable type `Ref`s are commonly used so it’s not a high priority.

---

<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 9, 2017, 12:37am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/3 "2017-02-09T00:37:03Z")

</div>

Still, we should really have this feature for 1.0 – the `Ref` pattern is usable but rather awkward.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [August 15, 2017, 6:10pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/4 "2017-08-15T18:10:23Z")

</div>

In my understanding, if we have globals with constant type, the performance loss of using globals disappears, correct?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 15, 2017, 6:27pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/5 "2017-08-15T18:27:59Z")

</div>

> [@e3c6](#):
>
> In my understanding, if we have globals with constant type, the performance loss of using globals disappears, correct?

Yes. And that seems to be the solution that’s settled on:

> <https://github.com/JuliaLang/julia/issues/8870#issuecomment-320101744>
>
> This keeps coming up, and rather than direct people to the performance tips, I f…eel like we should really just try to fix the issue. One relatively non-disruptive approach might be to emit code that accesses globals with a fast path that assumes that they have the same type that they currently have and a slow path that handles arbitrary type. A harder fix would be the compile-time version of that: generate code that assumes that globals retain their current type and invalidate it if the type changes. One might want to let compilation happen a couple of times before giving up and generating pessimistic general code.
> 
> Related: #265, #524, #964

Issue:

> <https://github.com/JuliaLang/julia/issues/964>
>
> Is it expected behaviour that I can't type annotate variable declarations in glo…bal scope? Example:
> 
> \`\`\` julia
> julia\> foo::Float = 0.1
> foo not defined
> 
> julia\> function bar()
> foo::Float = 0.1
> end
> 
> julia\> bar()
> 0.1
> \`\`\`

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [August 15, 2017, 6:50pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/6 "2017-08-15T18:50:22Z")

</div>

I really don’t understand what is the issue with simply allowing to state the type of gobal variables.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 15, 2017, 6:52pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/7 "2017-08-15T18:52:56Z")

</div>

> [@e3c6](#):
>
> I really don’t understand what is the issue with simply allowing to state the type of gobal variables.

Someone has to implement it.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [August 15, 2017, 7:08pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/8 "2017-08-15T19:08:19Z")

</div>

Ah, ok. I thought there was a deeper issue.

---

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [August 15, 2017, 8:16pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/9 "2017-08-15T20:16:38Z")

</div>

Apologies for a very basic question but: what does the current `const` not accomplish? I know it doesn’t force a variable to actually be constant, just that the type can’t be changed. But if it’s an error to do something like `const x = 3; x = 1.5`, doesn’t that mean the compiler now knows `x` is always an Int?

(Or is it something like when `x` is redefined it’s run-time checked to ensure that the type isn’t changing, in which case…what does `const` do?)

---

<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:** [August 15, 2017, 11:46pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/10 "2017-08-15T23:46:31Z")

</div>

Any function compiled when `x` was `3` might still use the old value if you redefine the `const` (which is why you also get a warning).

---

<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:** [August 16, 2017, 3:26am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/11 "2017-08-16T03:26:31Z")

</div>

It would also be useful to be able to write `x::Int = 3` in global scope to indicate that `x` is not a constant value but that whatever value is assigned to `x`, it must be an `Int`. I should mention that this is currently a low priority since `x::Int = 1` in global scope is currently an error, which means that the feature can be added post-1.0 without breaking anyone’s code. That doesn’t mean that we want the features, but there’s a lot of work to do for 1.0 right now.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [August 16, 2017, 5:54pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/12 "2017-08-16T17:54:01Z")

</div>

In my opinion, a lot of the users of Julia are people that are not programmers and do not care about code style, like physicists or mathematicians running simulations. For the majority of these people, it is a lot easier to do prototyping code using global variables. Otherwise you are forced to think about a structure with functions and structs, which can be a distraction if your priority is to test an idea quick and dirty.

---

<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:** [August 16, 2017, 6:26pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/13 "2017-08-16T18:26:34Z")

</div>

That’s fine and all, but this isn’t really a style issue – writing code with lots of mutable global state is _inherently_ at odds with good performance. Avoiding global mutable state happens to also lead to better code, but that’s only a secondary beneficial effect. Of course, this is not accidental – the reader of the code is in the same predicament whether they are a person or a compiler: global mutable state is hard to reason about and it makes programs difficult to understand.

---

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [August 16, 2017, 9:52pm UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/14 "2017-08-16T21:52:38Z")

</div>

It makes sense that in general avoiding global state is good practice, especially in production code. When prototyping, however, it can be useful (I think). What is the idiomatic way to define semi-constants that multiple functions depend on? By semi-constants I mean variables (typically numbers, but they don’t have to be) that a) lots of functions reference and b) whose value doesn’t change much, e.g. they would be constants in production code but in interactive usage, the user may wish to experiment with different values.

A silly non-realistic but hopefully illustrative example: suppose I am interested in the `k`-th largest and smallest elements of arrays. I might have functions like

```julia
k = 3

function get_kth_smallest(arr)
  # reads global k
  ...
end
function get_kth_largest(arr)
  # also reads global k
  ....
end
function analyze(arr)
  k_smallest = get_kth_smallest(arr)
  k_largest = get_kth_largest(arr)
  ...
end

```

In this case, especially for interactive use, it’s convenient to rely on global `k`; the user knows that `k` changes iff the user changes it. But it’s bad to make `k` be `const`, because then the user can’t experiment with changing `k` - the compiled functions won’t update. The value `k` could be passed around as an argument to every function, but if many different functions rely on the value of `k`, then pretty much every function has to accept `k` as an argument so when that function calls another function, the value of `k` can be passed along. That’s already ugly with a handful of functions and one constant, and gets really bad with many functions and many constants.

Is the trick to have each function accept default arguments referencing a non-const global variable, e.g. `function get_kth_smallest(k = k)`? That way within the function there’s no reference to global state? In some tiny benchmarks I did, this seems to have a large relative but negligible absolute performance cost relative to using `const`.

---

<div class="post-metadata">

**Author:** ![tshort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tshort/32/43_2.png) [@tshort](https://discourse.julialang.org/u/tshort)\
**Post date:** [August 17, 2017, 1:35am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/15 "2017-08-17T01:35:19Z")

</div>

You may want to try different workflows to see how it suits you. I like to wrap code in a module then make changes, and run `include(fname)`. Then, you can put const on `k`. The Atom/Juno editor can evaluate in a module which is nice for interactive use for code wrapped in a module. A lot of folks like that workflow. You can also try [REPLinModule.jl](https://github.com/tshort/REPLinModule.jl) for a similar effect at the REPL.

With Tim Holy’s new [Revise.jl](https://github.com/timholy/Revise.jl), you don’t even need to wrap code in a module for most uses. Just edit/save, and it’ll automatically pick up changes. I’m looking forward to using this more.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [August 17, 2017, 2:13am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/16 "2017-08-17T02:13:06Z")

</div>

To illustrate @yuyichao’s point upthread, you can do

```julia
const kref=Ref{Int}(3)

function set_k(k::Int)
  kref[]=k
end

get_kth_smallest(arr) = arr[sortperm(arr)[kref[]]]

```

and the compiler will handle use of `kref[]` very efficiently. This is useful in `Main` (so, at the REPL) or any other module.

---

<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:** [August 17, 2017, 3:00am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/17 "2017-08-17T03:00:57Z")

</div>

This is very likely how type-annotated globals will be implemented. I.e. when you write:

```julia
k::Int = 3

function set_k(k′::Int)
  global k = k′
end

get_kth_smallest(arr) = arr[sortperm(arr)[k]]

```

it will actually be lowered to something very much like the above. As I’ve said elsewhere, this is a post-1.0 change because this is a feature which will not break any code and right now we’re focused on stabilizing the features we have, rather than introducing any new ones. Gotta leave some goodies for 1.1!

---

<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:** [August 17, 2017, 5:24am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/18 "2017-08-17T05:24:58Z")

</div>

Slightly off-topic:  
I found that one of the main reasons I wanted to use globals, especially when quickly prototyping was physical constants and other model parameters:

```julia
const g = 9.81
const rho_w = 1000.0
...
press(h) = rho_w*g*h`
...

```

Instead now I use [https://github.com/mauro3/Parameters.jl:](https://github.com/mauro3/Parameters.jl:)

```julia
@with_kw struct Phys # edited typo here
  g::Float64 = 9.81
  rho_w = 1000.0
  # ...
end
press(h,p::Phys) = p.rho_w*p.g*h

p = Phys()
press(10,p)

```

There is a bunch of other useful helpers in that package, such as unpacking of values from the structs. I found that the convenience provided with this package is enough to stop me using globals, even when prototyping.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 9, 2023, 4:44am UTC](https://discourse.julialang.org/t/julia-1-7-and-below-do-not-have-constant-type-globals-julia-1-8-implemented-typed-globals/1989/19 "2023-01-09T04:44:18Z")

</div>

Since Julia 1.8, Julia does _now_ have constant-type globals:

> <https://github.com/JuliaLang/julia/pull/43671>
>
> This is an initial proposal for supporting typed globals based on #43455.
> The s…yntax for this is either \`global x::T\` or just doing \`x::T = 1\` in
> global scope. It is even supported to add these annotations to globals
> from inside functions. ~~The type declaration will then be applied when
> the method is defined and inside the function body conversion to the
> specified type will happen automatically, similar to type annotations
> for local variables.~~
> 
> ~~This conversion will not be applied if the assignment is not done inside
> the same scope of the type annotation however. This could potentially be
> supported as well, but the problem is that this would mean any
> assignment to a global variable - typed or not - would need to go
> through a call to \`convert\` first, since lowering can't know if a given
> binding already has a type annotation. This probably wouldn't be a good
> thing for latency and sysimage size and would add an invalidation risk.~~
> 
> Any assignment to a global now adds a conversion step and a type
> assertion, similar to how type annotations work inside local scopes.
> 
> It is allowed to refine a type annotation, but there will be a warning.
> Widening the type or changing it to any other type that is not a subtype
> of the previous one is an error, since that could cause cached compiled
> code to become invalid.
> 
> replaces #43455
> closes #964

> **[Julia 1.8 Highlights](https://julialang.org/blog/2022/08/julia-1.8-highlights/#typed_globals)**
>
> Highlights of the Julia 1.8 release.
