Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do the plus and unary plus behave strange in array syntax?

Following this question on the plus operator I have a follow-up question. We know the difference between plus and uplus, and thus that 1+2 resolves to 3, just as 1++2 or even 1++++++++2. The strange thing happens in array syntax, consider this example:

>> [1 ++ 2]
ans =
     1     2 % Two unary plusses
>> [1 + + 2]
ans =
     3 % A normal plus and a unary one
>> [1++2]
ans =
     3 % A normal plus and a unary one

The same works with multiple plusses, [1 +++..+++ 2], so with all plusses consecutively in the middle generates [1 2], all other combinations (as far as I tested) result in 3.

As far as I know spaces are of limited importance in MATLAB; exp(3*x/y) is the same as exp( 3 * x / y ). There is a use for them in creating arrays: [1 2] will generate a 1 -by- 2 array, and there are a few other uses, but separating operators is not one of them.

Therefore my question: Why do [1 ++ 2] and [1 + + 2] resolve differently?

Note that the minus and uminus have the same behaviour, and that the parser is magic enough to parse [1;;;3++ + + +--+ + ++4,;;;,;] perfectly fine to [1;7].

like image 927
Adriaan Avatar asked Oct 05 '18 11:10

Adriaan


1 Answers

My suspicion is that this has to do with how numeric literals are parsed. In particular, consider the following complex examples:

>> [1+2i]

ans =

   1.0000 + 2.0000i

>> [1 +2i]

ans =

   1.0000 + 0.0000i   0.0000 + 2.0000i

>> [1 + 2i]

ans =

   1.0000 + 2.0000i

There's a conflict between space as an array separator and space as a part of a complex number.

I believe the parser was written such that it tries to make sense of complex numbers (versus complex arrays) as reasonably as possible. This can easily lead to non-trivial behaviour in parsing expressions involving addition/subtraction and whitespace.


To be a bit more specific:

1 ++ 2 might parse as 1 +2, since multiple unary pluses are still a unary plus, and a unary plus can only act on the 2.

But 1 + + 2 might parse as 1 + (+ 2) where the latter plus is consumed as a unary plus, leaving 1 + 2 which is a single "complex" number.


A further follow-up after an inquisitive comment from @Adriaan:

[...] [1 ++ + 2] is [1 2], but [1 + ++ 2] is 3

So my proper guess would be that the parser moves from right to left.

  • [1 ++ + 2] -> [1 ++ (+ 2)] -> [1 ++ 2], versus
  • [1 + ++ 2] -> [1 + (++ 2)] -> [1 + 2].

This would also imply that any combination of [1 + ...2] (where there is only one plus in the first connected block of pluses) will give you [3] whereas if the first block of pluses contains two or more you will get [1 2]. A few pseudorandom tests seemed to verify this behaviour.

Of course until The MathWorks makes their parser open-source or documented we can only guess.

like image 83