It’s also a question of how to build matrices, and how to separate the elements of a row within a matrix. To demonstrate using row vectors:

```
julia> ([1-2+3], [1 -2+3], [1 -2 +3], [1- 2+ 3])
([2], [1 1], [1 -2 3], [2])
```

Add a comma and it throws an error:

```
julia> [1 -2 +3,]
ERROR: syntax: unexpected comma in array expression
```

similarly,

```
julia> [1 -2, +3]
ERROR: syntax: missing separator in array expression
```

This is because commas are used only for building one-dimensional arrays, i.e. column `Vector`

s, and that’s incompatible with matrices and other multidimensional arrays.

To do arithmetic on elements of the vector, spaces around the operator must be symmetric:

```
julia> [1-2, +3]
2-element Vector{Int64}:
-1
3
julia> [1 - 2, +3]
2-element Vector{Int64}:
-1
3
```

(more precisely, if there’s space on the left-side of the operator, then if there is no space on the right-side of the operator it will not be treated as a binary operator but instead as a unary operator.)

To build a higher-dimensional array such as a matrix, use semicolons or newlines:

```
julia> [1 -2 +3; -4 +5 -6]
2×3 Matrix{Int64}:
1 -2 3
-4 5 -6
```

In this expression, it becomes perfectly clear why these parsing rules work this way.

You can also build a column vector using semicolons or newlines instead of commas, because column vectors are just the tiniest subset of multi-dimensional arrays:

```
julia> [1; 2; 3]
3-element Vector{Int64}:
1
2
3
```

let’s do some arithmetic:

```
julia> [1+1; 2+2; 3+3]
3-element Vector{Int64}:
2
4
6
```

But add funny spaces around elements, and you can get an error:

```
julia> [1+1; 2 +2; 3+3]
ERROR: ArgumentError: argument count does not match specified shape (expected 3, got 4)
```

Julia’s parser is very clever for this specific reason—within the bounds of `[]`

, it’s assumed that expressions will be space-delimited for matrix-building, and so parsing rules needed to be made to handle this. And then, similar parsing rules are applied when we call macros without parentheses because we’re using spaces again as a separater between arguments.

It’s just something to be mindful of; you’ll run into it sooner or later anyway, either when building arrays or when calling macros, so it’s best to just adopt habits of symmetrical whitespace around operators. Symmetrical whitespace is a good habit anyway for code legibility.

Note that these considerations *only apply to plus and minus*, which are the only operators which can either be binary or unary; other operators don’t act like this:

```
julia> ([1/2*3], [1 /2*3], [1 /2 *3], [1/ 2* 3])
([1.5], [1.5], [1.5], [1.5])
```

Best to adopt good whitespace habits anyway.

**Edit:**

Note that it could have been decided, instead of having whitespace-dependent rules for when `+`

and `-`

would become unary operators, to simply wrap expressions in parentheses within matrices:

```
julia> [1 (-2) (+3)]
1×3 Matrix{Int64}:
1 -2 3
```

Then there would be no room for confusion surrounding this topic, neither within arrays nor in macro calls.

However, building large matrices would become a pain. Julia’s creators, being math-centric folks who love matrices, chose to prioritize succinctness in matrix building even though it calls for some context-dependent whitespace-dependent parsing rules.

I’m partial to math myself (after all, math is the closest thing we have to a universal language), so I can’t fault them for that. But it does demonstrate quite nicely how decisions in a language design will necessarily revolve around the priorities of its authors.