ES 3.1 : 'true' as absolute or relative?

# Thomas L. Shinnick (16 years ago)

I was reading some parsing/lexing code when I thought to question how named literals were being handled - 'true', 'false', and 'null'. So I went back to the 3.1 spec and then tested with four well-known ES implementations, FF3, Opera9, Chrome, and IE7. If anything, I'm less confused but now more worried at the difference between practice and (apparent) definition of how to handle these literals.

For reference, some parts of the 3.1 Annex A Grammar: Identifier :: See 7.6 IdentifierName but not ReservedWord

    ReservedWord ::                              See 7.5.1
        Keyword
        FutureReservedWord
        NullLiteral
        BooleanLiteral

    BooleanLiteral ::                                See 7.8.2
        true
        false

    PropertyName :                               See 11.1.5
        IdentifierName
        StringLiteral
        NumericLiteral

    PrimaryExpression :                              See 11.1
        ...
        Identifier

    MemberExpression :                               See 11.2
        ...
        MemberExpression . IdentifierName

And some testing with the four current implementations of ES:

  FF      b=new Object(); b.true = false; b.true;    --> 'false'
  Chrome  b=new Object(); b.true = false; b.true;
          SyntaxError: Unexpected token true
  Opera   >>> b=new Object(); b.true = false; b.true;
          Asynchronous script compilation
          Syntax error : line 1 of unknown script :
          Expected identifier
          b=new Object(); b.true = false; b.true;
          ----------------------^
  IE7     b=new Object(); b.true = false; b.true;
          1234567890123456789
          Line:  1
          Char:  19
          Error: Expected identifier

  FF      a = { true: false, false: true }; a.true;  --> 'false'
  Chrome  a = { true: false, false: true }; a.true;
          SyntaxError: Unexpected token true
  Opera   >>> a = { true: false, false: true }; a.true;
          Asynchronous script compilation
          Syntax error : line 1 of unknown script :
          Expected token: '}'
          a = { true: false, false: true }; a.true;
          ----------^
  IE7     a = { true: false, false: true }; a.true;
          Line:  1
          Char:  7
          Error: Expected identifier, string or number

(for completeness, note similar results are obtained for a = { if: false, then: true }; a.if; FF is agreeable, the others are not)

  FF      a = { true: false, false: true }; with (a) true;    --> 'true'
          a = { truth: false, lies: true }; with (a) truth;   --> 'false'
      (the others reject keyword 'true' as already shown)

The ES 3.1 draft spec appears to say that 'true' and the others are valid 'Identifier's for use in at least the two places tested above, PropertyName and MemberExpression.

Testing shows that only FireFox allows this, or at least does in two of three tests above. But given the failure under the 'with' construction, I wonder how well it understands the literal truth. (Or is that explained by rule "PrimaryExpression : Identifier" ?)

So....

Was it intended that the named literals 'true', 'false', and 'null' (and the keywords) were to be included as valid Identifier's?

How disturbing is it that most of the implementations disagree with this definition?

# Allen Wirfs-Brock (16 years ago)

This all seems reasonable. The standard in effect for the implementation you ran your tests on is ES3 (perhaps with some implementation defined extensions). The ES3 grammar does not allow reserved words (such as true and false) to be used as a PropertyName or to the right of the period in a MemberExpression. Your tests verify that most implementations conform to that restriction while FF has a "non-standard" extension that allows reserved words (or at least the ones you tested) to be used in those contexts.

ES3.1 intentionally adopted the FF extension as a standard part of the language, so when the other implementation are eventually updated to support ES3.1 they should no long report errors for your test cases.

The distinction between Identifer and IdentifierName was introduced into the ES3.1 grammar in order to describe this change.

From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Thomas L. Shinnick Sent: Thursday, April 02, 2009 4:01 PM To: ES Discuss Subject: ES 3.1 : 'true' as absolute or relative?

I was reading some parsing/lexing code when I thought to question how named literals were being handled - 'true', 'false', and 'null'. So I went back to the 3.1 spec and then tested with four well-known ES implementations, FF3, Opera9, Chrome, and IE7. If anything, I'm less confused but now more worried at the difference between practice and (apparent) definition of how to handle these literals.

For reference, some parts of the 3.1 Annex A Grammar: Identifier :: See 7.6 IdentifierName but not ReservedWord

   ReservedWord ::                               See 7.5.1
       Keyword
       FutureReservedWord
       NullLiteral
       BooleanLiteral

   BooleanLiteral ::                                 See 7.8.2
       tru
       false

   PropertyName :                                See 11.1.5
       IdentifierName
       StringLiteral
       NumericLiteral

   PrimaryExpression :                               See 11.1
       ...
       Identifier

   MemberExpression :                                See 11.2
       ...
       MemberExpression . IdentifierName

And some testing with the four current implementations of ES:

 FF      b=new Object(); b.true = false; b.true;    --> 'false'
 Chrome  b=new Object(); b.true = false; b.true;
         SyntaxError: Unexpected token true
 Opera   >>> b=new Object(); b.true = false; b.true;
         Asynchronous script compilation
         Syntax error : line 1 of unknown script :
         Expected identifier
         b=new Object(); b.true = false; b.true;
         ----------------------^
 IE7     b=new Object(); b.true = false; b.true;
         1234567890123456789
         Line:  1
         Char:  19
         Error: Expected identifier

 FF      a = { true: false, false: true }; a.true;  --> 'false'
 Chrome  a = { true: false, false: true }; a.true;
         SyntaxError: Unexpected token true
 Opera   >>> a = { true: false, false: true }; a.true;
         Asynchronous script compilation
         Syntax error : line 1 of unknown script :
         Expected token: '}'
         a = { true: false, false: true }; a.true;
         ----------^
 IE7     a = { true: false, false: true }; a.true;
         Line:  1
         Char:  7
         Error: Expected identifier, string or number

(for completeness, note similar results are obtained for a = { if: false, then: true }; a.if; FF is agreeable, the others are not)

 FF      a = { true: false, false: true }; with (a) true;    --> 'true'
         a = { truth: false, lies: true }; with (a) truth;   --> 'false'
     (the others reject keyword 'true' as already shown)

The ES 3.1 draft spec appears to say that 'true' and the others are valid 'Identifier's for use in at least the two places tested above, PropertyName and MemberExpression.

Testing shows that only FireFox allows this, or at least does in two of three tests above. But given the failure under the 'with' construction, I wonder how well it understands the literal truth. (Or is that explained by rule "PrimaryExpression : Identifier" ?)

So....

Was it intended that the named literals 'true', 'false', and 'null' (and the keywords) were to be included as valid Identifier's?

How disturbing is it that most of the implementations disagree with this definition?