Pop Quiz

Pop Quiz

  • Comments 21

Every non-trivial language has "gotchas". Here's one. Consider the following JScript, which creates an object and sets some fields to zero:

var x =
{
  0       : 0,
  123     : 0,
  1.23    : 0,
  blah    : 0,
  "dude!" : 0,
  "-1.23" : 0
};

A little weird, but it works just fine. How about this?

var x = { -1 : 0 };

That fails with the message "expected identifier, string or number".

Pop quiz: what the heck is going on here? Surely that is an "identifier, string or number", no?

  • I guess it attempts to create a named field "-1" and set it to 0. However since this is an invalid field identifier, it fails.
  • Bzzt. Try again. As you can see above, "-1.23" is a valid field identifier. Why should -1 be illegal when "-1.23" is legal?
  • Negative indices not allowed?
  • Why not?
  • It's seems it's evaluating the minus sign as an operator instead of an indication of "below zero". Thus, it's looking for an identifier, string or number before the minus to get the left hand side of the subtraction operation.
  • Because "-1.23" is a string and -1.23 is a float? Since I'm not a jscript kinda person I'm not sure.
  • Larry: But in the example above, 1.23 works, so it can't be a float vs string issue.

  • The 1.23 works because it is positive. The "-1.23" works because it is in quotes. I think the people above had it right. I'm just summing up what they said.
  • because "-1.23" is a string, and -1 isn't.

    My best guess, is that in Javascript 1.23 is a number, and - is a high priority operator. Hence -1.23 is not a number, but an expression. I also found that if +1 is the key, rather than just 1, then it also fails with the same error message.
  • Anderson got it.

    Holy cow, twenty-six minutes from question to correct answer. Don't you people have jobs? :-)

    Anything in quotes is a string, and any legal identifier is a legal identifier, but a number preceded by a negative sign is an expression, not a numeric literal.

    There is a similar gotcha in VBScript:

    print typename(-32767-1) ' Integer
    print typename(-32768) ' Long

    A short integer can hold any number from -32768 to 32767, so why is the second example a long? Because -32768 is the negative operator applied to a literal long, not a literal short.
  • Oh, and Eric: I'm trolling blogs from home right now waiting to take daniel to his dress rehearsal :)

    That's why I have time for this.

    You should look at the time stamps on my "what's wrong with this code" posts - they're scary :)
  • Since we're talking about the quirks of numbers in object initializers...

    Why doesn't

    var x = { 08 : 0 };

    whine about being a malformed octal literal?

    var y = 08;

    does.
  • I don't get any error for either of those. Or are you talking about JScript .NET?

    I talked a bit about malformed octal here:

    http://blogs.msdn.com/ericlippert/archive/2003/10/23/53278.aspx
  • JScript .NET (jsc 7.10.3052 to be exact)
  • Ah, how interesting. That's a bug.

    I added the warning to the code path where an octal literal is evaluated as part of a numeric expression. Since as we've just seen, a label must not be an expression, the warning is never hit.

    In this case we're not looking to evaluate an expression as a number. We need that thing as a canonical string. So we need to turn it into a number, and then turn it back into a string. For some odd reason, the routine that the compiler uses to do that is the same routine as is used at runtime by parseInt, rather than the routine used by the compiler in the main line expression evaluator. parseInt, being a runtime function, doesn't produce compile-time warnings.

    I'm not sure why the compiler author made that choice -- I didn't write that part of the compiler.
Page 1 of 2 (21 items) 12