It’s unfortunate JS considers null to be of type ‚object‘. I think that in most practical circumstances and definitely when a number comes from a Java primitive you can omit the null check as Java primitives can’t be null, though.
Hannes > Am 16.08.2016 um 16:16 schrieb João Paulo Varandas <joaovaran...@inpaas.com>: > > Hi Hannes. > > Thanks for reviewing this. Seeing it from this perspective: > > Longs are just like JS Number wrappers. > > Made me believe the situation was not that bad too. Telling developers to > 'unwrap' numbers using " x = Number(x); " would not be a bad idea. > > With that in mind, any number comparison would have to be made unwrapping > data first ... But, we would also need to test nulls first, because: > > While "null == 0" yields false, and obviusly "null === 0" yields false. > Number(null) === Number(0) would yield true. > > Thus, we would need: > > function unwrapNumber(x) { > return x == null ? null : Number(x); > } > > And also, to tell developers to call unwrapNumber() everytime they need to > compare a Number ... > > I don't know if you agree with me, but now I see this as an anti-pattern. > > > --- > > Anyway... It seems that all the fuzz is because of that "bug" with Long > numbers and double. And I'm sorry that I did not look further into that issue. > > Maybe we should look further into that, and try to make that any number below > Number.MAX_SAFE_INTEGER (9007199254740991), work the way is expected inside > JS evaluations ... > > > > > > > > > > João Paulo Varandas > +55 11 99889-2321 > joaovaran...@inpaas.com > > > 2016-08-16 6:23 GMT-03:00 Hannes Wallnöfer <hannes.wallnoe...@oracle.com>: > After exploring various options I don’t think there’s anything we can do to > go back and treat longs like numbers in Nashorn. > > The ECMA spec is quite clear that there are numbers and object, and > comparison of the latter is by reference, not value. So having some kind of > in-between states is not really an option. Making longs numbers again would > be quite a small and harmless change within the language (without reverting > to longs as internal data type). Precision would be lowered to doubles for > large longs, but that wouldn’t be a problem for most users. > > However, the problems starts where longs as numbers inherit from > Number.prototype. Of course, all methods in Number.prototype are specified > for double values, and the toString methods collides with toString in > java.lang.Long. Having a toString method that rounds large longs to the > nearest double value is a no-go. Nor is extending all methods in > Number.prototype to handle longs are viable options. > > There is one issue we need to fix to improve handling of longs and other > instances of java.lang.Number though (thanks to Attila for first pointing > this out): Currently, java.lang.Numbers not treated as numbers in the > ToPrimitive operation with Number hint. This means less-than/greater-than > operators will treat those number objects as strings instead of converting to > double. I filed a bug for this, and will back port it to JDK 8u: > > https://bugs.openjdk.java.net/browse/JDK-8163945 > > All things considered, there are some things that make me think the situation > is not as bad as some seem to believe. For one, the new treatment of Longs > (with the fix for the bug above) is consistent with how JavaScript Number > objects/wrappers are treated. Comparing two Number wrappers for the same > value will also evaluate to false with both == and === operators, while > comparing them to the primitive number with == will evaluate to true. > > new Number(1) == new Number(1) // false > new Number(1) === new Number(1) // false > new Number(1) == 1 // true > new Number(1) === 1 // false > > So Longs are just like JS Number wrappers. They are object wrappers for > numeric values. If needed they can easily converted to primitive numbers by > calling the global Number() function without „new“ keyword, eg: > > if (typeof x === „object“) > x = Number(x); > > This is a common pattern in JavaScript even without Java longs, so I think > it’s acceptable. > > Hannes > > > > Am 05.08.2016 um 15:45 schrieb Hannes Wallnöfer > > <hannes.wallnoe...@oracle.com>: > > > > Hi Joao Paulo, > > > > thanks for the report. > > > > We do realize that this change caused problems for a lot of people, and we > > are sorry for that, and thinking how we can improve things. > > > > I still think we were right to remove longs as internal number > > representation. But maybe we went to far with this, and should allow people > > to deal with longs as numbers, assuming they are all right with an eventual > > loss of presentation. > > > > This needs some discussion and thinking and experimentation. I’ll get back > > to you after the weekend. > > > > Hannes > > > > > > > >> Am 05.08.2016 um 04:40 schrieb João Paulo Varandas > >> <joaovaran...@inpaas.com>: > >> > >> By the way, I just found out some bugs filed about Long objects: > >> https://bugs.openjdk.java.net/browse/JDK-8162771 > >> https://bugs.openjdk.java.net/browse/JDK-8161665 > >> > >> And a twitter discussion: > >> https://twitter.com/provegard/status/755010492112986112 > >> > >> I'd like to bring this up again if we have more room for discussion ... > >> -- > >> > >> 2 Long values returned from a database and sent to a javascript evaluation > >> code can't be compared the way it should in JavaScript... If I have some > >> validation code, I don't know if the source is some JavaScript input > >> (number), or the source is a database query (object/Long/Integer/Double). > >> > >> It's really hard to decide when sometimes x==y should be compared as > >> x.equals(y) and sometimes not... and sometimes, at the same point in code > >> I should do a lot of conditional operations, to resolve a simple > >> comparison... and that comparison does not work if the data source is a > >> Java object or a JavaScript object. > >> > >> The problem with the current solution is that comparison between different > >> types would never work ... > >> > >> Seeing that > >> jjs> new java.lang.Long(2147483648) == "2147483648" > >> returns true > >> > >> But > >> jjs> new java.lang.Long(2147483648) == new java.lang.Long(2147483648) > >> returns false > >> > >> Is something really hard to accept ... > >> And that "equals" approach will work ONLY if I compare Long to Long. And I > >> see this as a regression when talking about evaluating JavaScript code. > >> > >> > >> > >> Sorry about the long post, but I would really appreciate if we could > >> revalidate this and think about what the current situation represents from > >> ecmascript's point of view. > >> > >> > >> > >> > >> > >> -08-04 22:43 GMT-03:00 João Paulo Varandas <joaovaran...@inpaas.com>: > >> Sorry Tomas. > >> > >> Either you did not read the message(which would be indeed a beginner's > >> mistake), or you are misleading the discussion. > >> > >> What you said, about equality and references would be true if we were > >> talking about Java code. This is jdk8-nashorn's mailing list and I'm > >> talking about JavaScript evaluation inside the JVM. > >> > >> > >> Comparison operators inside the script engine follow JavaScript rules and > >> not Java rules. > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> João Paulo Varandas > >> +55 11 99889-2321 > >> joaovaran...@inpaas.com > >> > >> > >> 2016-08-04 20:08 GMT-03:00 Tomáš Zíma <to...@tzima.cz>: > >> A classical beginner's mistake. You are using Java objects and comparing > >> references, not the values, so this is expected behavior. Simply compare > >> the objects using equals(). > >> > >> > >> On 4.8.2016 15:48, João Paulo Varandas wrote: > >> Hi guys! > >> > >> It seems that version 1.8.0_101 has a bug in equality for same java data > >> types (java.lang.Long). > >> > >> Check that: > >> jjs> new java.lang.Long(10) == new java.lang.Long(10) > >> false > >> > >> Oops!? > >> > >> See the gist: > >> https://gist.github.com/joaovarandas/51567bd3b576d48a4c574d60d5a60ba3 > >> > >> The results for all types should be ... > >> == true > >> === true > >> equals true > >> > >> But for java.lang.Long and java.math.BigDecimal: > >> == false > >> === false > >> equals true > >> > >> Maybe we could expand the test to other classes too, but the issue ... > >> - It does happen in 1.8.0_101. > >> - It does not 1.8.0_91. > >> - It does happen with other classes (BigDecimal). > >> - It does not happen with String. > >> - It does not happen with Integer. > >> > >> > >> I understand this is not an expected behavior. For now I'm rolling back > >> to 1.8.0_91 in my environments. > >> > >> > >> > >> Do you me to file a bug? > >> > >> Thanks > >> J > >> > >> > >> > >> > >> > >> > >> "Esta mensagem, incluindo seus anexos, pode conter informacoes > >> confidenciais e privilegiadas. > >> Se voce a recebeu por engano, solicitamos que a apague e avise o remetente > >> imediatamente. > >> Opinioes ou informacoes aqui contidas nao refletem necessariamente a > >> posicao oficial da Plusoft." > >> > >> "Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO > >> AMBIENTE" > > > > > > "Esta mensagem, incluindo seus anexos, pode conter informacoes confidenciais > e privilegiadas. > Se voce a recebeu por engano, solicitamos que a apague e avise o remetente > imediatamente. > Opinioes ou informacoes aqui contidas nao refletem necessariamente a posicao > oficial da Plusoft." > > "Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO > AMBIENTE" >