The motivation for `y = x`

evaluating to `x`

is this:

- The value that
`y`

actually ends up with can be arbitrarily different from `x`

since assignment to `y`

can implicitly call `convert`

, which can do anything.
- Since Julia is expression-oriented, we want
`y = x`

to be an expression and evaluate to some value.
- The classic way to make chained assignment work is to parse
`z = y = z`

as `z = (y = x)`

and have `y = x`

evaluate to the value you want to be assigned to `z`

.

If the value of `x`

and the value that `y`

gets are the same, then it doesn’t matter whether `y = x`

evaluates to `x`

or `y`

because they’re the same. But due to point 1, they’re not the same in Julia—this is true in many languages, but it’s worse for us because `convert`

is user-extensible so someone can do something arbitrarily whacky. But even a relatively innocuous conversion like `Int`

to `Float64`

could be problematic. I’m going to simulate `z = y = x`

where `y = x`

evaluates to `y`

instead of `x`

by writing out `y = x; z = y`

:

```
function f1()
# z = y = 1.0
y = 1.0; z = y
@assert y === 1.0
@assert z === 1.0
end
```

Ok, here’s a version where there’s spooky action at a distance:

```
function f2()
local y::Int
# ... lots of code here ...
# z = y = 1.0
y = 1.0; z = y
@assert y === 1
@assert z === 1.0
end
```

Now we get an assertion error because a type annotation on `y`

has “infected” the type of `z`

even though the intention of the code is to initialize both `y`

and `z`

with `1.0`

independently. We expect `y`

to be forced to `Int`

but we don’t expect that to affect `z`

.

With typed globals these days, this gets worse because the type annotation could be anywhere at all, e.g.:

```
# in some other file:
global y::Int
function f3()
global y
# z = y = 1.0
y = 1.0; z = y
@assert y === 1
@assert z === 1.0
end
```

Same assertion error but the spooky action at a distance can be arbitrarily distant.

All that being said, I think a better way to solve the issue would have been to parse chained assignment as a single construct instead of as a binary operation with right associativity. Then we could lower `z = y = x`

like this instead:

```
tmp = x
y = tmp
z = tmp
z
```

So the assignements are done independently and the entire expression evaluates to the value of the leftmost assignee. I would consider that a desirable change for (hypothetical) Julia 2.0, and probably not terribly breaking because I don’t think many people will be relying on chained assignment evaluating to the RHS.