Well, if you think about it, the inner for
always iterate first…
It is just that when you write for
s before the content of the loop, the inner is the second one, and when you write them after, in the comprehension, the inner is the first one.
And whether or not you are in a compression, for x y
is always translated to for x, for y
Hum… Now that I am on my computer and not on my phone anymore, I was able to tests some things and there is still something to discuss:
# The four following functions are equivalent :
function loop1(inner_range,outer_range,fun)
for o in outer_range
for i in inner_range
fun(o,i)
end
end
return nothing
end
function loop2(inner_range,outer_range,fun)
for o in outer_range, i in inner_range
fun(o,i)
end
return nothing
end
function comp1(inner_range,outer_range,fun)
[[fun(o,i) for i in inner_range] for o in outer_range]
return nothing
end
function comp2(inner_range,outer_range,fun)
[fun(o,i) for i in inner_range, o in outer_range]
return nothing
end
# this one behaves differently :
function comp3(inner_range,outer_range,fun)
[fun(o,i) for i in inner_range for o in outer_range]
return nothing
end
display("--loop1---------")
loop1([:i,:n],[:o,:u,:t],(x,y) -> display((x,y)))
display("--loop2---------")
loop2([:i,:n],[:o,:u,:t],(x,y) -> display((x,y)))
display("--comp1---------")
comp1([:i,:n],[:o,:u,:t],(x,y) -> display((x,y)))
display("--comp2---------")
comp2([:i,:n],[:o,:u,:t],(x,y) -> display((x,y)))
display("--comp3---------")
comp3([:i,:n],[:o,:u,:t],(x,y) -> display((x,y)))
outputs :
"--loop1---------"
(:o, :i)
(:o, :n)
(:u, :i)
(:u, :n)
(:t, :i)
(:t, :n)
"--loop2---------"
(:o, :i)
(:o, :n)
(:u, :i)
(:u, :n)
(:t, :i)
(:t, :n)
"--comp1---------"
(:o, :i)
(:o, :n)
(:u, :i)
(:u, :n)
(:t, :i)
(:t, :n)
"--comp2---------"
(:o, :i)
(:o, :n)
(:u, :i)
(:u, :n)
(:t, :i)
(:t, :n)
"--comp3---------"
(:o, :i)
(:u, :i)
(:t, :i)
(:o, :n)
(:u, :n)
(:t, :n)
So, the four first functions are behaving exactly as the logic i stated above said : the inner loop is always ran first.
But the last one, the for for
comprehension is not. In fact, there is no equivalent loop :
function loop3(inner_range,outer_range,fun)
for o in outer_range for i in inner_range
fun(o,i)
end
return nothing
end
will not compile. Therefore, it is an outsider. The correct comprehension that corresponds to the loops are the [ ... for, for]
and the [[... for ] for ]
versions, the comprehesion [... for for]
does not have a loop equivalent.
I see several ways out :
- Either we fix the
comp3
behavior so that is corresponds to others
- We remove the
comp3
possibility completely (my favorite).
- We had a
loop3
possibility that matches comp3
behavior
- We do nothing and warn people in the docs on loop comprehensions (maybe the safest way).