# Does Julia Need a C++ style \`static\` keyword?

**URL:** <https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176>\
**Category:** Internals & Design\
**Created:** [September 25, 2019, 8:24pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176 "2019-09-25T20:24:33Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 25, 2019, 8:24pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/1 "2019-09-25T20:24:33Z")

</div>

I was wandering whether there is currently a way of representing C++ style `static` variables in Julia. I haven’t found out how and I think they are pretty useful - especially when dealing with lots of object instances that share updatable properties.

C++ `static` keywords are used both within functions and within classes/types as system-wide but not necessarily global variables that can be updated for example [https://www.studytonight.com/cpp/static-keyword.php](https://www.studytonight.com/cpp/static-keyword.php)

As with C++ it would also be useful to be able to specify whether the static variable is thread local or not.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [September 25, 2019, 8:51pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/2 "2019-09-25T20:51:10Z")

</div>

`static` variables are really just a sign that you should have a variable outside the object. The julian replacement is just a const global variable.

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 9:07am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/3 "2019-09-26T09:07:26Z")

</div>

Hmm `const` not a stand-in for C++ `static`. For a start something like this doesn’t work:

```julia
const z = 0
function incrementZ()
  global z += 1
  return
end

incrementZ()
# WARNING: redefining constant z
z
# 1
incrementZ()
z
# 1

```

If I’m honest I don’t use `const` because I don’t really know how it works. The manual ([Essentials · The Julia Language](https://docs.julialang.org/en/v1/base/base/#const)) says `const` is for global variables **that do not change** - which is most certainly not the same idea as a C++ `static` variables. In addition I just managed to modify the global `const` variable `z` once which defeats the (manual’s) purpose of being constant. I guess I can make do with a regular global variable:

```julia
z = 0
incrementZ() # now works as expected.

```

But it doesn’t really “travel around” with your objects.

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [September 26, 2019, 9:21am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/4 "2019-09-26T09:21:00Z")

</div>

The idiomatic answer to this is `let`, I believe:

```julia
let z = 0
    global function incrementZ()
        z += 1
        return z
    end
end

println(incrementZ())
println(incrementZ())

```

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 10:16am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/5 "2019-09-26T10:16:29Z")

</div>

Thanks. That certainly looks useful and the variable is encapsulated away. In the case of classes I guess I can do something like:

```julia
mutable struct MyObject
  name::String
  age::Int64
end

let population = 0
  global function MakeMyObject(name::String, age::Int64)
    population += 1
    return MyObject(name, age)
  end
  global function getPopulation(::Type{<: MyObject})
    return population
  end
end

paul = MakeMyObject("Paul", 42)
getPopulation(MyObject) # 1
peter = MakeMyObject("Peter", 21)
getPopulation(MyObject) # 2

```

Since we can’t declare `MyObject(name::String, age::Int64)` outside the object declaration, we can do something like this, which is a bit awkward but still useful:

```julia
function MyObject((name, age)::Tuple{String, Int64})
  return MakeMyObject(name, age)
end

paul = MyObject(("Paul", 42))
getPopulation(MyObject) # 1
peter = MyObject(("Peter", 21))
getPopulation(MyObject) # 2

```

---

<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:** [September 26, 2019, 10:27am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/6 "2019-09-26T10:27:36Z")

</div>

You can use an inner constructor (eg in the example below, with validation):

```julia
let counter = 0
    global get_counter() = counter

    struct Foo
        x::Int
        function Foo(x)
            x > 0 || error("invalid x")
            counter += 1
            new(x)
        end
    end
end

```

which works like this (note counter is only incremented when you create a valid `Foo`):

```julia
julia> get_counter()
0

julia> Foo(1)
Foo(1)

julia> get_counter()
1

julia> Foo(-1)
ERROR: invalid x
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] Foo(::Int64) at /tmp/foo.jl:7
 [3] top-level scope at REPL[41]:1

julia> get_counter()
1

```

That said, global mutable state is difficult to reason about and may preclude some compiler optimizations, so it is generally avoided in Julia. Instead of porting code in C++ style, I would recommend finding another solution.

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 11:28am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/7 "2019-09-26T11:28:50Z")

</div>

Awesome! 🥳

I tried

```julia
let ...
  global struct MyType
  ...
  end
  ...
end

```

and got an error so I assumed that you couldn’t have globally accessible structs inside the `let` block - but you’ve just shown that you can. Many thanks!

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 11:32am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/8 "2019-09-26T11:32:47Z")

</div>

> [@Tamas\_Papp](#):
>
> That said, global mutable state is difficult to reason about and may preclude some compiler optimizations, so it is generally avoided in Julia

But the `counter` variable is not global, it’s in the let block so shouldn’t that be okay?

---

<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:** [September 26, 2019, 11:33am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/9 "2019-09-26T11:33:15Z")

</div>

> [@Tamas\_Papp](#):
>
> That said, global mutable state is difficult to reason about and may preclude some compiler optimizations, so it is generally avoided in Julia. Instead of porting code in C++ style, I would recommend finding another solution.

`const counter = Ref(0)`

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 11:44am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/10 "2019-09-26T11:44:08Z")

</div>

> [@ChrisRackauckas](#):
>
> `const counter = Ref(0)`

yes but if do that you’ll keep getting warnings when you modify the reference.

e.g.

```julia
counter = Ref(1)
# WARNING: redefining constant counter
# Base.RefValue{Int64}(1)

counter = Ref(2)
# WARNING: redefining constant counter
# Base.RefValue{Int64}(2)

```

I guess you could do something like:

```julia
counter.x += 1

```

Sorry but it seems kind of hacky to me. Should `const` really be used for something like that?

---

<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:** [September 26, 2019, 11:46am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/11 "2019-09-26T11:46:05Z")

</div>

It is global to the type (in the sense that various instances share the value).

If you absolutely need it, then go ahead and use this — but I think that mutable state is a bad habit, especially in Julia.

---

<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:** [September 26, 2019, 11:46am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/12 "2019-09-26T11:46:56Z")

</div>

You do

```julia
julia> const counter = Ref(1)
Base.RefValue{Int64}(1)

julia> counter[] = 2
2

```

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 11:56am UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/13 "2019-09-26T11:56:36Z")

</div>

> [@Tamas\_Papp](#):
>
> It is global to the type (in the sense that various instances share the value).
> 
> If you absolutely need it, then go ahead and use this — but I think that mutable state is a bad habit, especially in Julia.

But the instances (of the objects) don’t actually share the value - it’s actually encapsulated away from the objects themselves and exists only in that `let` scope. My main worry would be if there was any performance issue with doing it this way, other than that I would feel comfortable with it. I’m pretty sure that I don’t want it as a global variable like `const` would be.

As for `mutable` vs `immutable` I don’t worry too much about it as long as I can decide and that it is clear when I do decide. Sometimes like this I definitely want mutability, at other times I don’t. I also think having something as `const` and mutating it in what looks like an underhanded way seems worse. It’s sending two conflicting messages to the reader - that something is constant but not really. If something is a constant shouldn’t it _really_ be a constant?

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 12:01pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/14 "2019-09-26T12:01:55Z")

</div>

> [@ChrisRackauckas](#):
>
> const counter = Ref(0)

Or is the idea that the reference is `const` but not the content? So you are dealing with a fixed point in memory?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 26, 2019, 12:02pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/15 "2019-09-26T12:02:34Z")

</div>

precisely.

If I may ask, what are you trying to achieve? There may be a better way other than directly copying what you do in c++.

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 12:06pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/16 "2019-09-26T12:06:05Z")

</div>

> [@Sukera](#):
>
> If I may ask, what are you trying to achieve? There may be a better way other than directly copying what you do in c++.

The counter example is most relevant - sometimes you want to associate some property with all objects of a specific type whose value can be changed/fetched with a method/function and in C++ `static` is the way it’s done. In addition, the variable is the same for all the objects.

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 12:16pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/17 "2019-09-26T12:16:11Z")

</div>

I still find my self gravitating towards @Tamas_Papp’s solution because it’s a variable that’s basically hidden from `global` and can only be interfaced via methods and can be used in a similar way to static variable but it itself is still encapsulated from the type that uses it and you can enforce it with a type parameter by including `::Type{<:Mytype}` with the access method/function. Seems ideal to me.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 26, 2019, 12:20pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/18 "2019-09-26T12:20:44Z")

</div>

> [@dataDiver](#):
>
> the type by including `::Type{<:Mytype}` with the access method/function

As an aside, to me this seems like a much more cumbersome way to write

```julia
function example(::MyType)
   [...]
end

```

Type constraints don’t have to be explicitly told that they’re a type. This is equivalent since the `MyType` in your example is a `struct` and can’t be subtyped anyway. In julia, only `abstract type` types can be subtyped.

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 12:22pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/19 "2019-09-26T12:22:27Z")

</div>

> [@Sukera](#):
>
> As an aside, to me this seems like a much more cumbersome way to write

It is but I like it, it looks way cooler and more accomplished than `::MyType`. 😆

---

<div class="post-metadata">

**Author:** ![dataDiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datadiver/32/8174_2.png) [@dataDiver](https://discourse.julialang.org/u/dataDiver)\
**Post date:** [September 26, 2019, 1:07pm UTC](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176/20 "2019-09-26T13:07:32Z")

</div>

> [@ChrisRackauckas](#):
>
> const counter = Ref(0)

I just considered that the `let` method is probably thread local and the `const` way may be the same across threads - is that right?

[Next page](https://discourse.julialang.org/t/does-julia-need-a-c-style-static-keyword/29176.md?page=2)
