# Surprising evaluation order

**URL:** <https://discourse.julialang.org/t/surprising-evaluation-order/69555>\
**Category:** New to Julia\
**Created:** [October 11, 2021, 10:42am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555 "2021-10-11T10:42:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 11, 2021, 10:42am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555/1 "2021-10-11T10:42:20Z")

</div>

The following program

```julia
mutable struct Node{T}
    value::T
    left::Union{Nothing, Node{T}}
    right::Union{Nothing, Node{T}}
end
const Tree{T} = Union{Nothing, Node{T}}

function rotateright1(tree::Node{T}) where T
    save1 = tree.left.right
    tree.left.right = tree
    save2 = tree.left
    tree.left = save1
    tree = save2
    tree
end

function rotateright2(tree::Node{T}) where T
    tree, tree.left, tree.left.right =
        tree.left, tree.left.right, tree
    tree
end

tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                 Node("C", nothing, nothing))
println(rotateright1(tree))
println(rotateright2(tree))

```

prints

```julia
Node{String}("P", Node{String}("A", nothing, nothing), Node{String}("Q", Node{String}("B", nothing, nothing), Node{String}("C", nothing, nothing)))
ERROR: LoadError: type Nothing has no field right

```

I’d expect `rotateright1`and `rotateright2` to behave identical but must be missing something?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [October 11, 2021, 11:09am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555/2 "2021-10-11T11:09:36Z")

</div>

> [@goerch](#):
>
> ```julia
> function rotateright2(tree::Node{T}) where T
> tree, tree.left, tree.left.right =
> tree.left, tree.left.right, tree
> tree
> end
> 
> ```

As far as I know this expands to

```julia
a = tree.left
b = tree.left.right
c = tree
tree = a
tree.left = b
tree.left.right = c

```

which doesn’t match your `rotateright1`. I don’t know what evaluation order you expected but

```julia
    tree.left.right, tree.left, tree =
        tree, tree.left.right, tree.left

```

should be a better match to `rotateright1`.

To see what evaluation order Julia actually uses you can do

```julia
@code_lowered rotateright2(tree)

```

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 11, 2021, 11:19am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555/3 "2021-10-11T11:19:04Z")

</div>

Testing this

```julia
mutable struct Node{T}
    value::T
    left::Union{Nothing, Node{T}}
    right::Union{Nothing, Node{T}}
end
const Tree{T} = Union{Nothing, Node{T}}

function rotateright1(tree::Node{T}) where T
    save1 = tree.left.right
    tree.left.right = tree
    save2 = tree.left
    tree.left = save1
    tree = save2
    tree
end

function rotateright2(tree::Node{T}) where T
    tree, tree.left, tree.left.right =
        tree.left, tree.left.right, tree
    tree
end

function rotateright3(tree::Node{T}) where T
    tree.left.right, tree.left, tree =
        tree, tree.left.right, tree.left
    tree
end

tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                 Node("C", nothing, nothing))
println(rotateright1(tree))
# println(rotateright2(tree)) # Errors
println(rotateright3(tree))

```

results in

```julia
Node{String}("P", Node{String}("A", nothing, nothing), Node{String}("Q", Node{String}("B", nothing, nothing), Node{String}("C", nothing, nothing)))
Node{String}("B", nothing, Node{String}("Q", nothing, Node{String}("C", nothing, nothing)))

```

Now even more confused;)

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [October 11, 2021, 11:23am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555/4 "2021-10-11T11:23:53Z")

</div>

> [@goerch](#):
>
> results in
> 
> ```julia
> Node{String}("P", Node{String}("A", nothing, nothing), Node{String}("Q", Node{String}("B", nothing, nothing), Node{String}("C", nothing, nothing)))
> Node{String}("B", nothing, Node{String}("Q", nothing, Node{String}("C", nothing, nothing)))
> 
> ```

Looks consistent with

```julia
julia> tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                        Node("C", nothing, nothing))
Node{String}("Q", Node{String}("P", Node{String}("A", nothing, nothing), Node{String}("B", nothing, nothing)), Node{String}("C", nothing, nothing))

julia> println(rotateright1(tree))
Node{String}("P", Node{String}("A", nothing, nothing), Node{String}("Q", Node{String}("B", nothing, nothing), Node{String}("C", nothing, nothing)))

julia> println(rotateright1(tree))
Node{String}("B", nothing, Node{String}("Q", nothing, Node{String}("C", nothing, nothing)))

```

Possibly you’re confused because you don’t actually give the same input to the different functions, `tree` gets updated by each call you make.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 11, 2021, 11:27am UTC](https://discourse.julialang.org/t/surprising-evaluation-order/69555/5 "2021-10-11T11:27:18Z")

</div>

Yeah, you are damned right!

The correction

```julia
mutable struct Node{T}
    value::T
    left::Union{Nothing, Node{T}}
    right::Union{Nothing, Node{T}}
end
const Tree{T} = Union{Nothing, Node{T}}

function rotateright1(tree::Node{T}) where T
    save1 = tree.left.right
    tree.left.right = tree
    save2 = tree.left
    tree.left = save1
    tree = save2
    tree
end

function rotateright2(tree::Node{T}) where T
    tree, tree.left, tree.left.right =
        tree.left, tree.left.right, tree
    tree
end

function rotateright3(tree::Node{T}) where T
    tree.left.right, tree.left, tree =
        tree, tree.left.right, tree.left
    tree
end

tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                 Node("C", nothing, nothing))
println(rotateright1(tree))
tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                 Node("C", nothing, nothing))
println(rotateright2(tree))
tree = Node("Q", Node("P", Node("A", nothing, nothing), Node("B", nothing, nothing)),
                 Node("C", nothing, nothing))
println(rotateright3(tree))

```

explains it for me. Thanks for your help.
