mathjs icon indicating copy to clipboard operation
mathjs copied to clipboard

Numeric keys disallowed in object expressions

Open gwhitney opened this issue 11 months ago • 10 comments

Describe the bug Unlike in JavaScript, numeric literals cannot be used as plain object keys.

To Reproduce math.evaluate('{0: 12-7, 1: 8+2}[2-2]') throws SyntaxError: Symbol or string expected as object key (char 2).

Discussion It appears that the parser knows exactly what the situation is, which suggests there is no technical reason why this expression couldn't be allowed in the mathjs expression language. Given that it is perfectly legal in JavaScript and evaluates to 5 as expected, I would recommend that the mathjs parser be extended to accept numeric literals as object keys.

In order for this to be useful, the mathjs evaluator will also need to be extended to allow numeric values in indexing into plain objects: currently math.evaluate('{"0": 12-7, "1": 8+2}[2-2]') throws TypeError: Cannot apply a numeric index as object property

Workaround for now One can convert both the keys and the index expressions to strings: math.evaluate('{"0": 12-7, "1": 8+2}[string(2-2)]') produces 5 as expected. But this is of course cumbersome.

gwhitney avatar Jan 17 '25 03:01 gwhitney

Yeah I guess it's fine to relax the parser and allow numeric keys. I think it would be good though to not support the dot notation (I think JS doesn't support that either).

josdejong avatar Feb 28 '25 15:02 josdejong

Great, as soon as I can I will work up a PR. As far as a numeric argument with dot notation, currently if foo=[3,4,5], then foo.1 returns [0.3, 0.4, 0.5] because it is interpreted as implicit multiplication. Unless you want to change this behavior and change it to an error because it's more likely to be someone mistakenly trying to use dot notation with a number, I would plan to leave that behavior alone.

gwhitney avatar Mar 01 '25 15:03 gwhitney

Thanks Glen. I agree that the most common case when someone enters foo.1 is to use dot notation and not implicit multiplication. I think it is ok to leave it as it is now, it is a bit of an edge case. If people run into issues with this we can implement throwing an error (asking the use to either use foo[1] or foo 0.1), but that will be a breaking change.

josdejong avatar Mar 03 '25 08:03 josdejong

Yes I have no objection to leaving it alone. I was just raising the point.

gwhitney avatar Mar 03 '25 14:03 gwhitney

I have a lot of experience working with types in typescript and I believe I can smoothly extend the object type to also allow numbers as object keys.

I hope to try making the object key type number | ${string} first and if that doesn't work, I'll find another approach

codegiyu avatar Jun 26 '25 21:06 codegiyu

@codegiyu thanks for your input. I think the work needed here is to make some adjustments in the behavior of expression parser, it is not a TypeScript related issue. Would you like to dive into this?

josdejong avatar Jun 27 '25 15:06 josdejong

@josdejong yes I would like to take a shot at it

codegiyu avatar Jun 27 '25 15:06 codegiyu

👍 thanks

josdejong avatar Jun 27 '25 15:06 josdejong

You're welcome

codegiyu avatar Jun 27 '25 15:06 codegiyu

@josdejong a PR is open and ready for review

codegiyu avatar Jun 30 '25 02:06 codegiyu