# Walrus operator

**URL:** <https://discourse.julialang.org/t/walrus-operator/38208>\
**Category:** Internals & Design\
**Created:** [April 25, 2020, 11:02pm UTC](https://discourse.julialang.org/t/walrus-operator/38208 "2020-04-25T23:02:44Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 25, 2020, 11:02pm UTC](https://discourse.julialang.org/t/walrus-operator/38208/1 "2020-04-25T23:02:44Z")

</div>

I came across the [walrus/assignment operator in Python 3.8](https://docs.python.org/3/whatsnew/3.8.html).

The idea is that you can make an assignment in the if-expression and the variable is only visible in the `if` and `elseif` blocks. Just wondering if there’s any discussion before whether it’s a good idea for Julia… or not.

Example if it were to exist in Julia:

```julia
x = [1,2,3]
if (n := length(x)) > 0
    println("There are $n elements in `x`")
else
    println("Sorry, nothing in `x`")
end

```

So, the variable `n` is not available outside of the if-block nor in the else-branch.

Currently, we could use a let-block to limit the scope of `n` but it would be available in all branches of the if-block. Maybe that’s good enough for most people…

---

<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:** [April 25, 2020, 11:19pm UTC](https://discourse.julialang.org/t/walrus-operator/38208/2 "2020-04-25T23:19:46Z")

</div>

AFAICT the main difference from a `let` is indention and that’s easily solvable with a macro. And python can’t do that since AFAICT they have neither `let` or macros.

I believe it is good to separate additional variable scope from the expression that uses it. (i.e. it’s a bad idea to encourage `if .... long expression ... (n := sth) ..... long expression`). The variable assignment should just come before where it is used. Note that the example you give is one of this case since `n` is not a `Bool`, you have to write sth like `if (n := length(x)) > 0` and it’s much cleaner to just write `@let n = length(x) if ... else ... end` instead.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 25, 2020, 11:22pm UTC](https://discourse.julialang.org/t/walrus-operator/38208/3 "2020-04-25T23:22:49Z")

</div>

Oh yeah… my example is flawed regarding the condition. I have just updated the post.

---

<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:** [April 25, 2020, 11:41pm UTC](https://discourse.julialang.org/t/walrus-operator/38208/4 "2020-04-25T23:41:32Z")

</div>

I think a more appealing example is the walrus operator used with the comprehension expressions. Something like `[y for x in range(3) if (y := 2 * x) > 1]` in Python.

Ref:

[https://github.com/JuliaLang/julia/issues/32905](https://github.com/JuliaLang/julia/issues/32905)

---

<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:** [April 26, 2020, 12:31am UTC](https://discourse.julialang.org/t/walrus-operator/38208/5 "2020-04-26T00:31:29Z")

</div>

That case is similarly easy to handle with a `let` around the generator though.

---

<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:** [April 26, 2020, 12:36am UTC](https://discourse.julialang.org/t/walrus-operator/38208/6 "2020-04-26T00:36:50Z")

</div>

It’s slow due to boxing and also not parallelizable (e.g., when reducing a lazy iterator constructed by the comprehension).

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [April 26, 2020, 1:46am UTC](https://discourse.julialang.org/t/walrus-operator/38208/7 "2020-04-26T01:46:11Z")

</div>

I’m not opposed to us getting this doo-hicky, but I don’t think it really helps with anything. It makes code shorter, but often more confusing! Is there any way a variable like this could be treated differently by the compiler for some kind of speed boost or something?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 26, 2020, 2:02am UTC](https://discourse.julialang.org/t/walrus-operator/38208/8 "2020-04-26T02:02:11Z")

</div>

The main reason Python needs this operator isn’t scoping but because `x = ...` doesn’t have a return value.

It’s kinda crazy that `if` statements don’t generally introduce scopes but this does?

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [April 26, 2020, 2:07am UTC](https://discourse.julialang.org/t/walrus-operator/38208/9 "2020-04-26T02:07:38Z")

</div>

So it the difference between the walrus operator in Python and our assignment operator is that the walrus operator makes a _local_ binding. We can do that already with the `local` keyword:

```julia
julia> my_list = [1,2,3,4];

julia> if (local m = length(my_list)) > 3
           println(m)
       end
4

julia> m
ERROR: UndefVarError: m not defined
...

```

---

<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:** [April 26, 2020, 2:12am UTC](https://discourse.julialang.org/t/walrus-operator/38208/10 "2020-04-26T02:12:29Z")

</div>

> [@tkf](#):
>
> It’s slow due to boxing and also not parallelizable (e.g., when reducing a lazy iterator constructed by the comprehension).

Those are mostly implementation details (iteration itself isn’t parallizable either, without change in semantics) but I do agree that it is somewhat useful in comprehension. Comprehension/generator is already a compact syntax so it should be OK to introduce something along the same style to allow the condition and the return value to share a state. However, for all the normal code blocks, having a normal `let` would still be better.

---

<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:** [April 26, 2020, 2:26am UTC](https://discourse.julialang.org/t/walrus-operator/38208/11 "2020-04-26T02:26:47Z")

</div>

> [@yuyichao](#):
>
> Those are mostly implementation details

I think it’s nice to come up with the surface syntax that is easily handled by the compiler.

> [@yuyichao](#):
>
> iteration itself isn’t parallizable either, without change in semantics

It is actually very useful to consider that the iterator comprehension is defining iterator transformation rather than the iterator itself. It makes parallel algorithms work naturally with the collections created by the iterator comprehensions, e.g., using the conversion of the iterator transformations to transducers ([Transducer as an optimization: map, filter and flatten by tkf · Pull Request #33526 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/33526)). But yes, it’s in a way a change in semantics.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 26, 2020, 2:31am UTC](https://discourse.julialang.org/t/walrus-operator/38208/12 "2020-04-26T02:31:33Z")

</div>

Ooops… I made a mistake.

Somehow I was led to believe that it would introduce a local scope from reading a random blog post but I just checked with a real example and [that’s not true](https://www.python.org/dev/peps/pep-0572/#scope-of-the-target). So, it seems that this operator is merely used for making code a little shorter. Sorry about the confusion 😅
