How does julia prioritize operations and array concatenation?

Why is it ok to write 1 .-A but not [A;1 .-A] ? Somehow, it only works with a space between - and A.
Is it because Julia prioritize the A;1 part over the 1 .-A part ? Is there any documentation on how and why julia prioritize one over the other ?

julia> A = rand(3,3)
3×3 Matrix{Float64}:
 0.740468  0.317305  0.247191
 0.734218  0.903331  0.647368
 0.115604  0.461894  0.854236

julia> [A;1 .-A]
ERROR: DimensionMismatch: mismatch in dimension 1 (expected 1 got 3)
Stacktrace:
 [1] _cs
   @ ./abstractarray.jl:1717 [inlined]
 [2] _cshp
   @ ./abstractarray.jl:1713 [inlined]
 [3] _cat_size_shape
   @ ./abstractarray.jl:1693 [inlined]
 [4] cat_size_shape
   @ ./abstractarray.jl:1691 [inlined]
 [5] _cat_t
   @ ./abstractarray.jl:1732 [inlined]
 [6] typed_hcat(::Type{Float64}, ::Int64, ::Matrix{Float64})
   @ Base ./abstractarray.jl:1881
 [7] typed_hvcat(::Type{Float64}, ::Tuple{Int64, Int64}, ::Matrix{Float64}, ::Vararg{Any})
   @ Base ./abstractarray.jl:2094
 [8] hvcat(::Tuple{Int64, Int64}, ::Matrix{Float64}, ::Vararg{Union{Number, LinearAlgebra.AbstractTriangular{T, A} where {T, A<:(Matrix)}, Adjoint{<:Any, <:Vector}, Bidiagonal, Diagonal, Hermitian{T, A} where {T, A<:(Matrix)}, SymTridiagonal, Symmetric{T, A} where {T, A<:(Matrix)}, Transpose{<:Any, <:Vector}, Tridiagonal, Matrix, Vector}})
   @ LinearAlgebra ~/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:422
 [9] top-level scope
   @ REPL[2]:1

julia> [A;1 .- A]
6×3 Matrix{Float64}:
 0.740468  0.317305   0.247191
 0.734218  0.903331   0.647368
 0.115604  0.461894   0.854236
 0.259532  0.682695   0.752809
 0.265782  0.0966693  0.352632
 0.884396  0.538106   0.145764

julia> 1 .-A
3×3 Matrix{Float64}:
 0.259532  0.682695   0.752809
 0.265782  0.0966693  0.352632
 0.884396  0.538106   0.145764

Julia is whitespace sensitive within [] brackets as this is used for matrix construction, e.g.

[1 2; 3 -4]

is a valid matrix with a negative element. If in doubt it’s best to just use brackets to clarify intent, i.e.

[A;(1 .-A)]

will work fine.

1 Like

IMO using the bracket syntax for concatenation is usually a bad idea for anything other than writing a literal matrix of numbers. vcat(A, 1 .-A) works fine, no special parsing rules, no need later to squint at whether you have a semicolon or a comma there later.

2 Likes

Also note that while

[A; 1 .-A]

fails because of whitespace, you can also just remove the whitespace

[A; 1.0.-A]