I have seen it mentioned before that:
function f((x,y))
is effectively transformed to
function f(temp)
x , y = temp
But I donβt think that it is documented anywhere how x , y = temp
is transformed.
Could somebody please explain?
I have seen it mentioned before that:
function f((x,y))
is effectively transformed to
function f(temp)
x , y = temp
But I donβt think that it is documented anywhere how x , y = temp
is transformed.
Could somebody please explain?
julia> Meta.@lower x , y = temp
:($(Expr(:thunk, CodeInfo(
1 β %1 = (Base.indexed_iterate)(temp, 1) β
β %2 = (Core.getfield)(%1, 1) β
β x = %2 β
β #s1 = (Core.getfield)(%1, 2) β
β %5 = (Base.indexed_iterate)(temp, 2, #s1) β
β %6 = (Core.getfield)(%5, 1) β
β y = %6 β
βββ return temp β
))))
Itβs just a slightly fancier version of manually unrolled iteration.
How about the destructuring of next
in the lowering of a for
loop?
Does it get lower straight to a getfield
?
What do you mean next
?
Interfaces Β· The Julia Language
for i in iter # or "for i = iter" # body end
is translated into:
next = iterate(iter) while next !== nothing (i, state) = next # body next = iterate(iter, state) end
I know that portion of the documenation is out of date it is more like:
next = iterate(iter)
next === nothing && @goto loop_end
@label loop_head
(i, state) = next
# body
next = iterate(iter, state)
next === nothing && @goto loop_end
@goto loop_head
@label loop_end
But it appears that lowering of for today may be breaking the interface by skiping the indexed_iterate
of destructuring and going straight to:
next = iterate(iter)
next === nothing && @goto loop_end
@label loop_head
i = getfield(next,1)
state = getfield(next,2)
# body
next = iterate(iter, state)
next === nothing && @goto loop_end
@goto loop_head
@label loop_end
Yup. We should add an assertion to guarantee that iterate
returns a tuple like itβs supposed to. Iβd guess itβs this way because for
loops are extraordinarily performance sensitive.
I think I understand the reasoning but check out the benchmark here