# Why no := operator for initializing variables

**URL:** https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949
**Category:** Internals & Design
**Created:** [June 15, 2021, 2:08pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949 "2021-06-15T14:08:23Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![peteole](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peteole/32/209790_2.png) [@peteole](https://discourse.julialang.org/u/peteole)
#### Post date: [June 15, 2021, 2:08pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/1 "2021-06-15T14:08:24Z")

</div>

Hi,  
I have been wondering if there is a reason for not making for not making the initialization of variables explicit. I think this is done very elegantly in golang with the “:=” operator. Like this one would know exactly when an entirely new variable shall be introduced (and one could also think about fixing a variable’s type at creation, maybe this would avoid some strange errors and enable further optimization).  
Also you could avoid accidentally overwriting a variable’s value when you are not aware that a variable with the same name exists in the current scope.  
So what did I miss in my considerations?

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [June 15, 2021, 2:15pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/2 "2021-06-15T14:15:00Z")

</div>

It might be good to be clear in your post as to if you are asking:

- Historically, when Julia was still very in flux, why was this decided not to be done / was this considered ?

vs

- Why not add this feature to the language now?

These are subtly different questions with different answers, and those answers come from different (but overlapping) people.

The historical question is a kinda interesting chill discussion.  
The feature request, is liable to be contentious.

---

<div class="post-metadata">

### Author: ![peteole](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peteole/32/209790_2.png) [@peteole](https://discourse.julialang.org/u/peteole)
#### Post date: [June 15, 2021, 2:29pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/3 "2021-06-15T14:29:29Z")

</div>

Well, it’s kind of both. I was wondering if

- there was a reason for not including this feature in julia historically or if it was just that it was not thought about
- and if the reasons, if existent, for not implementing this feature are still valid today.

Also of course you would have to consider that this would be a breaking change in tons of julia code so I know its hard to argue for it.

---

<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: [June 15, 2021, 2:43pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/4 "2021-06-15T14:43:57Z")

</div>

To answer a very small part of this, this would not allow further optimization. Variable scopes are fully determined at compile time already, so this wouldn’t give llvm any new information.

---

<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: [June 15, 2021, 2:45pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/5 "2021-06-15T14:45:38Z")

</div>

Are you aware of

```julia
let x = ...
   ...
end

```

? Sounds to me like this would address most points you brought up.

---

<div class="post-metadata">

### Author: ![peteole](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peteole/32/209790_2.png) [@peteole](https://discourse.julialang.org/u/peteole)
#### Post date: [June 15, 2021, 2:59pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/6 "2021-06-15T14:59:44Z")

</div>

I was not aware of that, maybe you are right. However I do not know if this is feasible if you just want to create a single variable since it blows up code size. Also it adds another layer of nesting which may be undesirable. However, maybe it would make sense to define

```julia
for i=1:10
   x:=i+1
   ...
end

```

as a shorthand for

```julia
for i=1:10
   let x=i+1
      ...
   end
end

```

So a := would just add a let… end - block to the innermost block of code  
?  
This would not be a breaking change and not require too much work to be done…

---

<div class="post-metadata">

### Author: ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)
#### Post date: [June 15, 2021, 3:01pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/7 "2021-06-15T15:01:41Z")

</div>

> [@peteole](#):
>
> - eason for not including this feature in julia historically or if it was just that it was not thought about
> - and if the rea

We already have scope keyword, like global and local. `:=` is not needed. Scope keywords are more flexible than `:=` because they can also be used on function declaration. Also, there’s no more benefit using `:=`, since there is no difference between `x := 1` and `local x = 1`. Instead, you should propose a `let` or `const` variable declaration syntax to avoid accidental overwrite.  
Another problem is that, `:=` is a syntax construction instead of a semantic one. It’s generally impossible to know which assignment statement actually initializing the variable, that is, the first one to assign the variable. Consider this multi-threading program:

```julia
parallel for i in 1:10
    x := i
end

```

So you don’t really know which `i` initializes the `x` variable…

---

<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: [June 15, 2021, 3:09pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/8 "2021-06-15T15:09:02Z")

</div>

> [@peteole](#):
>
> So what did I miss in my considerations?

AFAIK this was an explicit design choice: having different syntax for introducing variables into a scope and assignment is something that programmers used to Python, R, Matlab, etc, may find inconvenient.

This came up in the (epic) scoping discussions: having separate syntax for the two would have solved a lot of scope problems trivially — cf `(let ((x x-val)) ...)` in Lisp.

---

<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: [June 15, 2021, 3:20pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/9 "2021-06-15T15:20:51Z")

</div>

I actually don’t think that would be such an unreasonable proposal. I am assuming there could then only ever be one `:=` per variable name in each scope and multiple ones would be a syntax error? The main question here is just whether this pattern is used often enough to warrant its own syntax. I think this does warrant an issue on GitHub at least to see what others think.

---

<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: [June 15, 2021, 3:46pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/10 "2021-06-15T15:46:56Z")

</div>

I would love to have `a := 3` as a shorthand for `a::Int = 3` (and have it work in global scope)!

So I think `:=` could serve two purposes that often go together:

1. Make sure a variable is not re-declared by mistake.
2. Give the variable a fixed type inferred by the value on the right-hand side. This means you can fix the type without knowing/writing the type signature (which can be complex).

Plus, it’s nice for readability as the code clearly says “this is were the variable is first defined”.

I also wonder: would this not solve a lot of performance issues if it becomes the “default” declaration syntax (i.e. recommended when the flexibility of `=` is not needed)? I mean, this would give

- a nice syntax to declare globals with good performance.
- a simple way to catch type instabilities: declare with `:=` and you will get an error if you later assign a value that cannot be converted to the initial type.
- if we can make the parser/compiler a bit smarter this could also help with closure performance (see [#15276](https://github.com/JuliaLang/julia/issues/15276)).

---

<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: [June 15, 2021, 3:49pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/11 "2021-06-15T15:49:35Z")

</div>

AFAIK not requiring explicit declarations for locals was an explicit design choice for Julia. Cf eg

> [@Why not an even-harder scope?](https://discourse.julialang.org/t/why-not-an-even-harder-scope/50087/14):
>
> Having a lot of time thinking about it, I really believe that our current design is very close to optimal given just these assumptions: Locals may be implicitly declared by assignment The rules for all local scopes are the same The language has closures. There are languages where all variables have to be explicitly declared, i.e. you have to write var x or local x to declare a new local. This, of course, makes all problems relating to what scope an assignment assigns to go away: it’s the inne…

---

<div class="post-metadata">

### Author: ![tdunning](https://avatars.discourse-cdn.com/v4/letter/t/13edae/32.png) [@tdunning](https://discourse.julialang.org/u/tdunning)
#### Post date: [June 16, 2021, 8:23pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/12 "2021-06-16T20:23:01Z")

</div>

Having recently learned Go (where := is used very much), I was very pleased with the middle ground that they have in that kind of code between explicit scope and syntactic parsimony.

My own background is heavily influenced by an older tradition of Scheme (and Julia is very much of a Schemish flavor), as a result I find `let` to be a natural expression that has very nice and clear scope. I would have expected that my reaction to := would be more negative. In fact, I found Go’s syntax to work really well.

On the other hand, I don’t think that the benefits of := would be fully recognized without some of the other aspects of Go, notably its very intentionally opinionated nature. For instance, the way that Go polices unused imports, unused variables and simple definition structure really work together for a more maintainable world. That level of strictness occasionally binds, but the solution is always clear enough that it is easy to fix. It would be hard, however, to convince somebody from a very dynamic world of that fact without actually having them experience it first hand.

---

<div class="post-metadata">

### Author: ![skypuppy](https://avatars.discourse-cdn.com/v4/letter/s/54ee81/32.png) [@skypuppy](https://discourse.julialang.org/u/skypuppy)
#### Post date: [June 17, 2021, 12:52am UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/13 "2021-06-17T00:52:51Z")

</div>

That makes my head hurt. 🙂

---

<div class="post-metadata">

### Author: ![dstahlke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dstahlke/32/20483_2.png) [@dstahlke](https://discourse.julialang.org/u/dstahlke)
#### Post date: [June 17, 2021, 1:36am UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/14 "2021-06-17T01:36:31Z")

</div>

Perl had a similar feature where you would have to write

```julia
my $var = 0;

```

upon the first use. It’s like `int var = 0` in C but without the type. The advantages are code readability (a visible guarantee that this is the first use) and catching of typos. If you typo’d `$car = 1` later on, it’d be a syntax error. AFAIK the `my` keyword had no real effect other than causing an error if you didn’t use it.

Reverse compatibility was handled by having the user opt-in with `use strict`. These sorts of checks were useful enough that all well written code would have `use strict` on the first line.

Though you could claim having to declare variables is just a pain, I considered it to be an important code quality feature and missed it when switching to python.

---

<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: [June 17, 2021, 5:20pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/15 "2021-06-17T17:20:04Z")

</div>

This is certainly an interesting design direction that’s fun to think through. You would want something like this: `:=` is required to initialize a variable, `=` can only be used to update an existing variable. That would take some getting used to for people coming from Python, R or Matlab, who are unaccustomed to thinking about variable declaration much. Their question would likely be “what is the difference?” — I’ll leave that to someone else to try to answer in this hypothetical alternate universe (perhaps a different version of me).

It could, as you suggested, also declare the type of the variable to be the type of whatever the value that is assigned is. One of the reasons you don’t want variables to default to being type-const is that it’s fairly common for people who are using a REPL or doing other “fast and loose” work to reuse the same variable name like `x` for something different — say a float in one case and a string in another. The `:=` version `=` distinction could help with that: if `x :=` occurs twice, the second one creates a new, separate `x` variable. Any previous capture of `x` still reference the old version of `x` (which can no longer be modified except by a closure), any new capture references the new `x` with a different type. That’s slightly confusing but I think that it would be fine and people would be able to enter multiple examples in the same REPL, which is the main thing they want. And we’d have type-stable globals, which is pretty nice. So this:

```julia
x := 0
x = 1 # fine, works
x = "hello" # error, can't convert `String` to `Int`
get() = x # capture this `x`
set(v) = x = v # modify this `x`

x := "hello" # works, new `x`
get′() = x # capture new `x`

get() # returns 1
get′() # returns "hello"

x = "goodbye"
get′() # returns "goodbye"
get() # still returns 1

set(2) # only way we can change the old `x` now
get() # returns 2

```

So that’s pretty nice. You can reuse common variable names but `get`, `set` and `get′` get to assume consistent types, which seems good. Thinking through some examples. First closures that do and don’t modify an outer local:

```julia
function f()
    x := 1
    g() = x = 2 # modifies outer `x`
    h() = x := 3 # doesn't affect outer `x`
end

```

Now for loops. The first version has a new iteration variable in each iteration:

```julia
for i := 1:10
   # new `i` in each iteration
end
# `i` is undefined here

```

Next a version where the iteration variable is an outer local:

```julia
i := 0
for i = 1:10
    # same `i` in all iterations
end
# `i` is 10 here

```

Unclear what one would do with the `in` syntax that many people prefer. Do we just treat `in` the same way as `:=`? The assignment syntax for for loops seems strictly better in this design since it lets you choose between using an outer variable and having a new variable per loop iteration. Classic example of non-obvious interactions between different language features.

I can’t think of any other interesting example off the top of my head. Anyone think of any?

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [June 17, 2021, 6:34pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/16 "2021-06-17T18:34:25Z")

</div>

> [@StefanKarpinski](#):
>
> I can’t think of any other interesting example off the top of my head. Anyone think of any?

Could this type of syntax help for easier compiling and linking of standalone executables (slim executables without the julia runtime included) ?

---

<div class="post-metadata">

### Author: ![peteole](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/peteole/32/209790_2.png) [@peteole](https://discourse.julialang.org/u/peteole)
#### Post date: [June 17, 2021, 6:44pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/17 "2021-06-17T18:44:35Z")

</div>

However there I see the issue that casting should be somehow allowed, else

```julia
x:=1
x=1.5

```

would throw an error which may be undesired.  
I would only fix a type if the type is explicitly specified.

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [June 17, 2021, 7:06pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/18 "2021-06-17T19:06:24Z")

</div>

I was thinking that keeping the normal assignment behavior should continue, and if someone uses `:=` then you enforce the types, that way you can get the benefits of having a special assignment operator without losing the flexibility.

---

<div class="post-metadata">

### Author: ![sbuercklin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbuercklin/32/15728_2.png) [@sbuercklin](https://discourse.julialang.org/u/sbuercklin)
#### Post date: [June 17, 2021, 7:53pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/19 "2021-06-17T19:53:19Z")

</div>

I think then we would need a new type for variables initialized with `:=`. Otherwise, how do we know if a particular assignment can change the type of the LHS? If the initialization happens in the same scope, you could conceivably tag the variable and restrict it there, but if that variable is passed into a function you’d need a way to distinguish variables initialized with `:=` vs `=`

---

<div class="post-metadata">

### Author: ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)
#### Post date: [June 17, 2021, 9:44pm UTC](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949/20 "2021-06-17T21:44:20Z")

</div>

I think this is a bad idea: scoping is inherently a difficult and subtle concept which new (and old) users struggle with. But if `:=` becomes possible it will appear all over the place, and require a careful explanation (that no one will actually understand) very early on the docs… so the more verbose version with `let` sounds much better to me.

[Next page](https://discourse.julialang.org/t/why-no-operator-for-initializing-variables/62949.md?page=2)
