julia
julia copied to clipboard
inconsistencies with assignments in argument lists
Assignment in tuples and arrays
julia> x=65; [x,x|=0x20]
2-element Vector{Int64}:
97
97
julia> x=65; (x,x|=0x20)
(97, 97)
was made a syntax error at one point (in 0.3; see #4982, #4990 and closing commits), but it's allowed again (not sure if intentionally or not). But it leads to some fun inconsistencies:
julia> value = 1; (value, value + 1, value += 1, value += 1)
(3, 2, 2, 3)
julia> let value = 1; (value, value + 1, value += 1, value += 1); end
(1, 2, 2, 3)
Note that this isn't specific to tuples or arrays, but is the case for any kind of argument list:
julia> x=1; println(x, x+=1)
22
The underlying issue here seems to be that lowering often treats symbols just like SSA-values and doesn't take into account that evaluating other arguments before that symbol could change its value. Here's another fun inconsistency which evaluates differently to the example above:
julia> x=1; println(begin x end, x+=1)
12
@JeffBezanson would you agree with the assessment that this is a lowering bug?
That's bad, and there is a regression in here somewhere since in 1.0 I get
julia> function f(); global value; value = 1; (value, value + 1, value += 1, value += 1); end
julia> f()
(1, 2, 2, 3)
but (3, 2, 2, 3)
in more recent versions.
It seems to have broken in 1.1
already
I guess it's perhaps not surprising, but I noticed that this also affects string interpolation:
julia> value = 1; "$(value), $(value + 1), $(value += 1), $(value += 1)"
"3, 2, 2, 3"
julia> let value = 1; "$(value), $(value + 1), $(value += 1), $(value += 1)"; end
"1, 2, 2, 3"
Does Julia make any promises about the order in which function arguments in a function-call expression (or tuple arguments) are evaluated?
Yes, we should evaluate them left to right.