Strange white space dependence with @assert

Julia syntax is usually insensitive to white space, but I encountered a situation when @assert introduces a strange dependence on white space. Is this a bug? (I’m using Julia 1.6.0.)

julia> t = Int64[1,2];

julia> @assert t[1]+1 == t[2]

julia> @assert t[1] +1 == t[2]
ERROR: TypeError: non-boolean (Int64) used in boolean context
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> t[1]+1 == t[2]
true

julia> t[1] +1 == t[2]
true
julia> @macroexpand( @assert t[1]+1 == t[2] )
:(if t[1] + 1 == t[2]
      nothing
  else
      Base.throw(Base.AssertionError("t[1] + 1 == t[2]"))
  end)

julia> @macroexpand( @assert t[1] +1 == t[2] )
:(if t[1]
      nothing
  else
      Base.throw(Base.AssertionError((Base.Main).Base.string(1 == t[2])))
  end)

I would say it’s a bug.
But you can avoid it by using parantheses:

julia> @macroexpand( @assert( t[1] +1 == t[2] ) )
:(if t[1] + 1 == t[2]
      nothing
  else
      Base.throw(Base.AssertionError("t[1] + 1 == t[2]"))
  end)
2 Likes

I think it’s a quirk of macro parsing, that because the part after the space is a valid expression, it gets treated as a second argument:

julia> @show t[1]+1 == t[2];
t[1] + 1 == t[2] = true

julia> @show t[1]  +1 == t[2];
t[1] = 1
1 == t[2] = false

julia> @show t[1]  *1 == t[2];  # * cannot be a unary operator
t[1] * 1 == t[2] = false

The same is true inside matrix-building syntax:

julia> [t[1]+1]
1-element Vector{Int64}:
 2

julia> [t[1] +1]
1×2 Matrix{Int64}:
 1  1

julia> [t[1] + 1]  # symmetric space
1-element Vector{Int64}:
 2
3 Likes