# Typeconst proposal

**URL:** <https://discourse.julialang.org/t/typeconst-proposal/75953>\
**Category:** Internals & Design\
**Tags:** proposal, constants\
**Created:** [February 5, 2022, 11:15pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953 "2022-02-05T23:15:04Z")\
**Posts on this page:** 14\
**Page:** 2

<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, 9:19pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/21 "2022-02-07T21:19:35Z")

</div>

The warning used to be a lot less alarming but then people complained when redefining `const` bindings caused problem, so it was made more alarming.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 8, 2022, 5:38am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/22 "2022-02-08T05:38:14Z")

</div>

> [@simeonschaub](#):
>
> Even after #43671, reads from globals will still always be atomic, so while there might not be any type instabilities anymore, you probably still don’t want to use non-constant globals in performance sensitive contexts like tight loops.

A load of global is currently `unordered` which is even weaker than the weakest `monotonic` ordering we can use in the Julia programs. `monotonic` is called `relaxed` in C++ and it doesn’t have any power of “cross-thread communication” on its own (it basically only guarantees that no load/store tearing happen). Furthermore, it’s formally proven that various compiler optimizations are legal under C++ memory model (which does not necessarily mean LLVM does that for us \[1\]). In particular, hoisting out relaxed loads out of the loop is allowed (unless there are stronger atomic operations in the loop). Since `unordered` is weaker than `monotonic`, the load can be hoisted out. Indeed, in 1.7.1:

```julia
julia> mutable struct Var{X}
           x::X
       end

julia> const V = Var(Int[]);

julia> function f(n)
           a = nothing
           for x in 1:max(1, n)
               a = V.x
           end
           a
       end;

julia> @code_llvm debuginfo=:none f(1)
define nonnull {}* @julia_f_137(i64 signext %0) #0 {
top:
  %1 = load atomic {}*, {}**inttoptr (i64 139758282988048 to {}**) unordered, align 16
  ret {}* %1
}

```

(But no, I’m not recommending global mutable states.)

* * *

1. [https://www.youtube.com/watch?v=IB57wIf9W1k](https://www.youtube.com/watch?v=IB57wIf9W1k)

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [February 8, 2022, 6:13am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/23 "2022-02-08T06:13:03Z")

</div>

You are right, we currently only emit `unorderd` loads for global bindings.

I don’t think this example actually illustrates it though, since `T` is a constant and constants are [special-cased in codegen](https://github.com/JuliaLang/julia/blob/4abf26eec8c700f88acf9e395c1bdd67e49d2b56/src/codegen.cpp#L2383) so that the actual load is elided. All you are seeing here is the load from `V` of the field `x`, not the actual lookup of the global binding `V` from the module, right?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 8, 2022, 6:48am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/24 "2022-02-08T06:48:08Z")

</div>

I’m using `getfield` instead of `GlobalRef` to illustrate my point since I was too lazy to build your branch. Once the codegen emits the `unordered` load in the loop, what I pointed out holds independent of what syntax was used in the frontend. For example, I could have used

```julia
function f(v::Var, n)
    a = nothing
    for x in 1:max(1, n)
        a = v.x
    end
    a
end;

```

as an example. (A more important point is that `Var` holds a GC-manged object.)

> [@simeonschaub](#):
>
> All you are seeing here is the load from `V` of the field `x` , not the actual lookup of the global binding `V` from the module, right?

Yes, this is exactly what I wanted to show.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [February 8, 2022, 7:08am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/25 "2022-02-08T07:08:15Z")

</div>

Ah, I see! I think I was just a bit confused since you made `V` a constant global.

Indeed, you can actually observe the same behavior with #43671:

```julia
julia> v::Int = 1;

julia> function f(n)
           a = 0
           for x in 1:max(1, n)
               a = v
           end
           a
       end;

julia> @code_llvm debuginfo=:none f(10)
define i64 @julia_f_1262(i64 signext %0) #0 {
top:
  %1 = load atomic i64*, i64**inttoptr (i64 140085820903256 to i64**) unordered, align 8
  %2 = load i64, i64* %1, align 8
  ret i64 %2
}

```

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 8, 2022, 7:14am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/26 "2022-02-08T07:14:00Z")

</div>

Thanks for checking this! And yes, I agree it was confusing now that I think that this thread has been discussing `const` vs `global`. I should’ve used `f(v::Var, n)` as an example.

---

<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:** [February 8, 2022, 8:42am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/27 "2022-02-08T08:42:40Z")

</div>

> [@StefanKarpinski](#):
>
> The warning used to be a lot less alarming but then people complained when redefining `const` bindings caused problem, so it was made more alarming.

I submitted [Clarify the warning on redefining const globals by antoine-levitt · Pull Request #44073 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/44073)

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 8, 2022, 10:57am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/28 "2022-02-08T10:57:52Z")

</div>

> [@StefanKarpinski](#):
>
> I don’t get this insistence people have to not be allowed to do this. If you don’t like it, don’t do it. Is there something I’m missing here?

Thanks for asking! I don’t think you’re missing anything but it’s clear we have different perspectives (probably related to our disagreement on stacked enviroments). This has been on my mind for a while, I’ll probably write a blog post at some point, but here’s a first attempt to explain my point of view:

It’s hard to write reliable software, let’s say, software that has very low probability of behaving wrongly. There are so many ways to make mistakes and so many things to keep in mind while coding. Compilers and other tools can find problems, and of course writing tests helps a lot, but for the rest it’s on me: when writing serious code I’m always thinking “did I think of every possibility? is there anything that can go wrong here?” etc. It’s a huge mental load.

In this context, the most valuable thing a language or tool can give me is “Don’t worry about _that_, it can’t happen!”. But this only works if correctness comes first. _Not_ as a tradeoff with convience and performance. Imagine a `FastLock` type that is 50% faster and works correctly 99.999% of the time… I’m not interested at all. Zero percent. So back to our `const` rebinding, “typical that everything works” is a big no-no.

About the warning, I was happy when it was [improved](https://github.com/JuliaLang/julia/pull/35119). I remember when I discovered the `const` rebinding feature it used to say simply `WARNING: redefining constant` and I felt bad in the stomach… I wanted Julia to be perfect, and here was a case where the compiler finds a problem that can cause undefined behavior, and I just get a casual warning? I felt like “no way! how could the devs be so careless about correctness?” The new warning however suggests that more weight is given to correctness.

Maybe that’s what bothers me the most: what the feature communicates about the language’s priorities. It suggests that a convenient REPL experience is more important than a correct program. Worse: the feature is also available in package code, so it seems that restricting the feature to interactive use was deemed not worth the effort (or the weight of convenience was too pressing to wait).

Somehow this really hurt my sensibilities… My perspective is influenced by a background in fields that put a premium on reliability (industrial robotics and drone control software), but I’m probably not alone. Maybe Julia is losing something here in terms of contributions: I can imagine that a number of software engineers have looked at the language and were turned off by the relatively small consideration given to reliability. They might be precisely the people who would contribute to make important packages more “professional” in terms of reliability, documentation, etc. (no offense to the developers of these packages, their work is much appreciated!).

To end on a positive note: I have the feeling that things are moving in a good direction. The most offensive footguns are progressively retired (cf. the scary warning we’re discussing here and the documentation changes [here](https://github.com/JuliaLang/julia/pull/40092) and [here](https://github.com/JuliaLang/julia/pull/32974) for `@pure`).

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 8, 2022, 11:03am UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/29 "2022-02-08T11:03:05Z")

</div>

To elaborate on the `const` rebinding itself:

I don’t really see the value of the feature when as the warning says the correctness of the program is not guaranteed afterwards. Even for development, I would be annoyed when anything goes wrong that I must wonder if maybe that’s because of a `const` rebinding. And in the odd case where I want to copy-paste `const` definitions several times in the REPL, it’s not that hard to wrap the whole thing in `module XXX ... end`. Not worth having the language seem so careless about correctness.

An option to make the warning an error doesn’t make much sense for me, but the opposite, having an opt-in flag to allow `const` rebinding would be an improvement. As would be restricting the feature to interactive use.

I don’t mind if we allow executing `const a = 4` several times. There’s no problem as long as the new assignment is `===` identical to the previous one.

It gets trickier with something like `const A = [1,2,3]`. I suppose even in this simple case a reassignment can produce an invalid program?

I like the idea of @StefanKarpinski of having full support for `const` rebinding, i.e. as a heavy operation that recompiles all necessary code, for interactive use. It still contradicts the semantics of `const` and would be terrible for readability, so I guess it should produce an error in non-interactive use.

---

<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:** [February 8, 2022, 1:21pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/30 "2022-02-08T13:21:38Z")

</div>

> [@sijo](#):
>
> I wanted Julia to be perfect, and here was a case where the compiler finds a problem that can cause undefined behavior, and I just get a casual warning? How could the devs be so careless about correctness?

I really do not understand how do you shift the blame to the devs, if you use this feature, the burden is on you, just do not use it. Also, undefined behavior was always (in my C/C++ knowledge) exactly this **undefined** behaviour, the compiler is free to do whatever, but in this case, instead, it guarantees that you will receive an warning.

> It suggests that a convenient REPL experience is more important than a correct program.

Again, you can never use this feature. I use it. It is a probability thing. I redefine the `const`, re-run the code, and if what I have changed does exactly what I expected, then I know no problem happened, and carry on; otherwise, I reload the REPL. It is not even that I do not care about reliability, it is that there is a test suit that will check things for me anyway at the end of the development cycle; I do not understand what I would gain from being slowed down in a previous step of the development cycle.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 8, 2022, 1:55pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/31 "2022-02-08T13:55:31Z")

</div>

> [@Henrique\_Becker](#):
>
> I really do not understand how do you shift the blame to the devs,

Sorry for the confusion! With this:

> How could the devs be so careless about correctness?

I was trying to reproduce an inner dialogue to describe how I _felt_, almost emotionally you could say, years ago on that day when I first stumbled on this feature. It’s **not** meant as an actual criticism of the developers. I have slightly edited my post to clarify it hopefullly.

> if you use this feature, the burden is on you, just do not use it

In general this doesn’t scale well to a team and even worse to an ecosystem that I don’t control. But in this particular case that might actually work… Assuming I’m also warned when `const` is “misused” in one of my dependencies, and assuming the warning doesn’t get lost in precompilation messages or whatever.

Anyway the point of my post was to answer @StefanKarpinski who was trying to understand my point of view. I actually worked a long time on that post trying to analyze and articulate my position and still apparently just produced more misunderstanding. Sorry.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [February 8, 2022, 4:11pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/32 "2022-02-08T16:11:19Z")

</div>

> [@sijo](#):
>
> In general this doesn’t scale well to a team and even worse to an ecosystem that I don’t control. But in this particular case that might actually work… Assuming I’m also warned when `const` is “misused” in one of my dependencies, and assuming the warning doesn’t get lost in precompilation messages or whatever.

Is there any package out there that actually redefines a constant? I agree that would be bad, but I have never seen that in the wild, which makes this a purely theoretical concern to me.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [February 8, 2022, 4:43pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/33 "2022-02-08T16:43:50Z")

</div>

Agreed, I think it’s quite unlikely. If it ever happens I guess it will be found quickly by users that see the warning. So it seems like one of those case where the “if you don’t like it, don’t do it” idea can work.

---

<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, 2022, 8:34pm UTC](https://discourse.julialang.org/t/typeconst-proposal/75953/35 "2022-02-09T20:34:35Z")

</div>

Thank you for taking the time to articulate it. I think the very high order reassurance that I can offer is this: you _only_ need to worry if code prints a warning. No warning, no worry. If there are any warnings when your code runs, read them and take them seriously.

[Previous page](https://discourse.julialang.org/t/typeconst-proposal/75953.md?page=1)
