# How to re-define a variable completely?

**URL:** <https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322>\
**Category:** New to Julia\
**Tags:** type\
**Created:** [June 14, 2023, 9:37am UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322 "2023-06-14T09:37:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lukas\_Hebing](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lukas_hebing/32/45778_2.png) [@Lukas\_Hebing](https://discourse.julialang.org/u/Lukas_Hebing)\
**Post date:** [June 14, 2023, 9:37am UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/1 "2023-06-14T09:37:30Z")

</div>

When I define a wrong (or unuseful) type to a variable declaration I get an error as expected:

```julia
my_var::Int64 = 3.2

```

However, when I continue to work in the REPL, it is impossible to re-define the variable:

```julia
my_var = 3.2

```

It seems, that the variable type is stored in the REPL. How can I clear or redefine the type without restarting the kernel?

---

<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:** [June 14, 2023, 9:56am UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/2 "2023-06-14T09:56:57Z")

</div>

You cannot really. The goal of `::Int64` is to ensure that that variable never changes its type away from an `Int64` and code might have been compiled with that assumption.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 14, 2023, 12:55pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/3 "2023-06-14T12:55:24Z")

</div>

And why does this does not raise an error? My intention often with type signatures in function arguments is also to try for type stability but than …

```julia
julia> foo(x::Int=0) = x=1.5
foo (generic function with 2 methods)

julia> foo(1.5)
ERROR: MethodError: no method matching foo(::Float64)
...

julia> foo(1)
1.5

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 14, 2023, 12:59pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/4 "2023-06-14T12:59:19Z")

</div>

What you guarantee with the type signature is that the _input_ value has to be of type `Int`. Internally, you are just assigning the label `x` to a new value. If you want that `x` to be `Int`, you need to annotate the type of that assignment as well:

```julia
julia> function foo(x::Int)
           x::Int = 1.5
       end
foo (generic function with 1 method)

julia> foo(1)
ERROR: InexactError: Int64(1.5)

```

(although flooding the code with these annotations is not really the idiomatic way to write type stable code in Julia, it would be very inconvenient and be against the nature of language).

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 14, 2023, 1:02pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/5 "2023-06-14T13:02:46Z")

</div>

> [@lmiq](#):
>
> nternally, you are just assigning the label `x` to a new value.

Yes, but is that what should not be allowed. That variable name is already type signed in function’s argument.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 14, 2023, 1:09pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/6 "2023-06-14T13:09:17Z")

</div>

Think of it as “names in boxes”.  
The function is a box. When you look for a name, it might look “outside the box” e.g. at its arguments, there it would find `x::Int`  
If you define `x= 1.5` then _in_ the “function box” you have a new name `x` (that the function would look first for) that is now a float. You basically introduced a local new name for something and gave it a type – that are different from the ones in the signature.  
You can for example avoid that way to “accidentally overwrite/mutate” your input. There this might be very useful.  
This “local name of the second `x`” is also forgotten afterwards again (at the end of the function).

Whether it might also be confusing with different types is of course a different story, but there might be good reasons to introduce locally something new under the name `x`.

---

<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:** [June 14, 2023, 1:19pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/7 "2023-06-14T13:19:08Z")

</div>

Julia allows annotating types in function parameters because it is necessary for multiple dispatch (one of the most, if not _the_ most, important trait of the language). Annotating types of global variables to disallow them changing type was introduced a long time after. And, if I am not wrong, annotating the type of local scope variables was introduced even later. So, I think the confusion is related to the fact that the two mechanisms have nothing to do with each other, and one did not exist until recently. Julia could **now** change the semantics of the language and make every function automatically annotate the type of each parameter inside the local scope preventing type change, but I think this would be breaking and would require Julia 2.0.

---

<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:** [June 14, 2023, 1:21pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/8 "2023-06-14T13:21:27Z")

</div>

Also, note that your example given an `InexactError` but the below does not:

```julia
julia> function f()
         a::Int = 1
         a = 2.0
         return a
       end
f (generic function with 1 method)

julia> f()
2

```

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [June 14, 2023, 1:55pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/9 "2023-06-14T13:55:12Z")

</div>

Honestly, I find it incomprehensible that we can impose that a variable has to dress with a certain cloth to enter that box (the function) but once inside it can change clothes to what ever it wants.

> [@Henrique\_Becker](#):
>
> ```julia
> function f()
> a::Int = 1
> a = 2.0
> return a
> end
> 
> ```

I couldn’t believe this one, but my computer confirmed it!!! So we impose a type and next that is ignored?

Edit: I see `a = 2.0` is converted to `Int`. `a = 2.1` errors.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 14, 2023, 2:33pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/10 "2023-06-14T14:33:42Z")

</div>

I think that would be useful, but still very limited. One could still migrate to a type-unstable assignment with:

```julia
function f()
    x::Int = 1
    y = x
    y = 2.1
    return y
end

```

Thus, the scope of the stability provided by the input value would be limited. The first time I heard about Julia (I guess back in 2015) it was suggested that something like this could be written:

```julia
julia> function f(x_in:Int)
           local x::Int = x_in
           local y::Int
           y = x
           y = 2.1
           return y
       end
f (generic function with 1 method)

julia> f()
ERROR: InexactError: Int64(2.1)

```

Giving to the user the “feel” of typed language if one wants to (it would be complete if the function compilation threw an error if any label is not declared with an explicit type). But even if that can have benefits in terms of some debugging (strictly typed languages do have these advantages), I’m not sure if I would have migrated from Fortran if that was required for a good programming workflow. Still, having a a sub-language with these guarantees would be certainly a welcome addition (I wouldn’t mind having `@strictly_typed` macro for that, and probably would find some use to it).

---

<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:** [June 14, 2023, 5:52pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/11 "2023-06-14T17:52:16Z")

</div>

Yes, a macro seems the best tool for an opt-in feature to have multiple dispatch annotations also restrict the variable types inside the function’s local scopes.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 14, 2023, 6:11pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/12 "2023-06-14T18:11:12Z")

</div>

> [@joa-quim](#):
>
> Honestly, I find it incomprehensible that we can impose that a variable has to dress with a certain cloth to enter that box (the function) but once inside it can change clothes to what ever it wants.

That sounds like the most natural thing in the world to me.

Though, in fact it is a _value_ that you are letting in through the door, not a variable. That you later bind that name to a different value is also pretty normal for a dynamically typed language.

If there’s anything I’m uncomfortable with, it’s the _opposite_. It does not seem right for a dynamic language to put the type on the variable, which is now permissible in some circumstances.

---

<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:** [June 14, 2023, 6:19pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/13 "2023-06-14T18:19:02Z")

</div>

> [@DNF](#):
>
> It does not seem right for a dynamic language to put the type on the variable, which is now permissible in some circumstances.

A typed global variable reduces the set of objects it can be rebound to. This is a softer version of `const`. Are you also opposed to `const`?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 14, 2023, 6:21pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/14 "2023-06-14T18:21:02Z")

</div>

I have close to zero experience writing macros, but that seems feasible, doesn’t it? A macro that checks, first, that the input values of a function are all concrete. Then, checks if every label inside the function is always associated to the same type, and if the value is mutable, to the same value. That doesn’t seem too different from what the inference machinery does, or what `@code_warntype`, Chutlhu and JET can do.

Probably the fact that this macro doesn’t exist is a sign that when one gets used to Julia we don’t want to write code with strict types anymore, ever (and that those tools already do a descent job in solving type-inference issues).

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 14, 2023, 6:22pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/15 "2023-06-14T18:22:59Z")

</div>

> [@kristoffer.carlsson](#):
>
> Are you also opposed to `const`?

I know. And in principle, yes 😉 Though that would be pretty inconvenient.

I just said I was uncomfortable with it because it messes with my (surely incomplete) mental model, which defines dynamically typed languages as “types belong to values, not variables”.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 14, 2023, 6:32pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/16 "2023-06-14T18:32:02Z")

</div>

> [@lmiq](#):
>
> A macro that checks, first, that the input values of a function are all concrete. Then, checks if every label inside the function is always associated to the same type, and if the value is mutable, to the same value. That doesn’t seem too different from what the inference machinery does, or what `@code_warntype`, Chutlhu and JET can do.

Those aren’t things that macros can do by themselves — macros don’t know about types or inference, they only know syntax (how things are “spelled”). `@code_warntype` is a trivial macro that just rewrites an expression into a call to a function that hooks into the compiler, it’s not doing any of the type checking itself:

```julia
julia> macroexpand(Main, :(@code_warntype sqrt(2)))
:(InteractiveUtils.code_warntype(sqrt, (Base.typesof)(2)))

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 14, 2023, 6:36pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/17 "2023-06-14T18:36:33Z")

</div>

> [@joa-quim](#):
>
> Honestly, I find it incomprehensible that we can impose that a variable has to dress with a certain cloth to enter that box (the function) but once inside it can change clothes to what ever it wants.

I look at it like this: The function signature `foo(x::Int)` is a filter on what type of _values_ (not variables) are accepted through the door. Once inside, the value is offered a jacket (“x”). This jacket does not belong to the value, and the jacket can be put on a different ‘guest’ (or on the back of a chair) at a later point.

Remember, when you pass a value to a function, referred to by a name, it generally changes name once through the door. If you call `foo(a)`, `a` becomes `x` once inside.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 14, 2023, 8:48pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/18 "2023-06-14T20:48:52Z")

</div>

> [@joa-quim](#):
>
> Honestly, I find it incomprehensible that we can impose that a variable has to dress with a certain cloth to enter that box (the function) but once inside it can change clothes to what ever it wants.

Type-unstable variables are useful sometimes, and `::` already means different things in different contexts. On right-hand expressions, it’s a `typeassert`. On left hand side of assignments, in `local` statements, or `struct` fields, it restricts the type with `convert`s.

Neither can be said to resemble argument annotations more. For example, is `function f(x::Int) end` supposed to resemble the call `f(1::Int)` or a variable restriction `x::Int=1`? So it’s free to do something different: dispatch.

---

<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:** [June 14, 2023, 8:51pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/19 "2023-06-14T20:51:57Z")

</div>

Just to clarify, my idea of a macro would be:

1. macro looks at the signature of the function (that is all spelt out in code, no need to access any runtime information).
2. macro changes the code of the function to add some lines in the following format at the start of the function body `name_parameter_1::type_parameter_1 = name_parameter_1`…

This is, what I thought initially was just a handy way to copy-paste the parameters of the function to the function body, in a way the parameter variables are now type-annotated with the same types they have in the parameter list.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 14, 2023, 9:08pm UTC](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322/20 "2023-06-14T21:08:23Z")

</div>

Food for thought on that macro that enforces input type stability:

```julia
julia> function foo(x::AbstractFloat)
         x::AbstractFloat = x
         x = 2 # convert(AbstractFloat, 2)
         x
       end;

julia> typeof(1.5f0), typeof(foo(1.5f0))
(Float32, Float64)

julia> function bar(x::AbstractFloat)
         x::typeof(x) = x
         x = 2 # convert(typeof(x), 2)
         x
       end;

julia> typeof(1.5f0), typeof(bar(1.5f0))
(Float32, Float32)

```

[Next page](https://discourse.julialang.org/t/how-to-re-define-a-variable-completely/100322.md?page=2)
