1

When playing around with JavaScript syntax it struck me that the following code will throw an error in SpiderMonkey and V8 engines:

var a = 1, b = 1;
a++++b;

This to me is strange, since the following works perfectly fine:

var a = 1, b = 1;

a+++b; // = 2; (Add a and b, then increase a)
// now a == 2 and b == 1

a+++-b; // = 1; (add a and -b, then increase a)
// now a == 3 and b == 1

In addition, the following would be nonsensical code:

var a = 1, b = 1;
a++ ++b; // throws an error

My argument is now that if a+++b is equivalent to a++ + b, and not to a+ ++b, and a+++-b is equivalent to a++ + -b, then a++++b can only be interpreted as a++ + +b in order for it to be valid JavaScript code. Instead, the engines insist that a++++b is interpreted as a++ ++b, by operator precedence.

This to me is in contrast with the logic that the engines implements using the / symbol, as explained here, to distinguish between division and regular expressions. An example

var e = 30, f = 3, g = 2;

e/f/g; // == 5

e
/f/g; // == 5

/f/g; // is equivalent to new RegExp("f","g")

Here the argument is that because /f/g does not make sense as division in the last line, it is interpreted as a regular expression.

Obviously the / symbol gets a special treatment, in order to distinguish between division and regular expressions. But then why do ++ and -- not get a special treatment as well? (That is, outside operator precedence)

A second question is why operator precedence is not called only when the code is has multiple valid interpretations.

Community
  • 1
  • 1
TrenchCode
  • 11
  • 2

1 Answers1

2

In the code a++++b you have two distinct statements: a++ and ++b with nothing to combine them. The + operator in the context of a++ + +b is actually a type converter (meant for turning strings into numbers) and has a different order of precedence which follows the others in the list.

CoryG
  • 2,429
  • 3
  • 25
  • 60
  • 1
    Yes, the `+` is also used for "casting" - for example `+"10"` will convert that `string` type to a `number` type – iSkore Jan 22 '17 at 13:46
  • @CoryG Could you elaborate your answer? I fail to see how this this different from what I have already discussed in my question. – TrenchCode Jan 22 '17 at 14:07
  • @TrenchCode Sorry if I was brief, I've been writing a parser, tokenizer, and abstract syntax tree system for a custom language modeled very closely against JS for the past several months so I tend to take for granted how much of a PitA it was to wrap my head around the precedence initially. JS is designed to be parsed on the fly very quickly, as a result you don't have a clear precedence like in many other languages, that list is about as good as it gets without sifting through the spec. Things like `//` comments and `+` type converters are parsed before and after that whole list (cont) – CoryG Jan 22 '17 at 14:12
  • @TrenchCode It's relatively simple for a parser to do an off-the-bat iteration through the text (or do it in conjunction with a single parsing loop preceding everything else) to determine what is inside or outside of a string then what is inside or outside of a comment so they do those before checking for operators (why bother doing syntax parsing if it's just text in the form of a literal or a comment?) Likewise, converters are kind of a hacked-on-after-the-fact feature of JS because things were supposed to be type-invariant but it didn't quite work out that way in practice so they don't fit – CoryG Jan 22 '17 at 14:15
  • @TrenchCode Trying to standardize JavaScript (or any language, programming or spoken) into a very strict syntax without loopholes rarely works perfectly (I can't actually think of a single instance in spite of knowing a few dozen) - they are designed to describe arbitrarily complex things and be extensible while the people who write them inherently can't know all the use cases - beyond version 1 of a language you get inconsistencies. – CoryG Jan 22 '17 at 14:17