We debated this issue within the team, and it turned out to be a fairly deeper 
rabbit hole than initially expected.

This comparison falls under the case 9 (Object compared to String) of the "The 
Abstract Equality Comparison Algorithm" <http://es5.github.io/#x11.9.3>. It 
requires that we invoke ToPrimitive(x), which in turn requires evaluation of 
[[DefaultValue]] internal property on the enum object. The behavior of 
[[DefaultValue]] on ordinary JS objects is described in 
<http://es5.github.io/#x8.12.8> and we could choose to follow it: if the object 
has a "toString" callable property, invoke it. So by that token, we could 
indeed invoke toString() on a POJO here.

However, a runtime is at liberty to redefine [[DefaultValue]] for host objects 
too, with the restriction that "If a host object implements its own 
[[DefaultValue]] internal method, it must ensure that its [[DefaultValue]] 
internal method can return only primitive values." (still section 8.12.8). 

In ES5, any object not being a native JS object is a "host object" - all POJOs 
are considered host objects in Nashorn.

Going to section 8.6.2, "Object Internal Properties and Methods" 
<http://es5.github.io/#x8.6.2> it says that every object (even host objects) 
must have all properties in Table 9 – [[DefaultValue]] included, but also says: 
"However, the [[DefaultValue]] internal method may, for some objects, simply 
throw a TypeError exception."

So with all that in mind, we have two choices for specification-compliant 
implementation of this comparison:

1. invoke toString() on the POJO when compared to a String (and everywhere else 
in the runtime where specification prescribes ToPrimitive() conversion – this 
can have some ripple effects…), or
2. throw TypeError when toPrimitive(x) is invoked on a POJO.

From this PoV, returning false from that comparison indeed seems incorrect; we 
should either return true, or throw a TypeError. Problem is, we have hard time 
deciding which way to go. JS is a very permissive language and it really allows 
you to convert almost anything to almost everything. While we're in the pure 
JS-land, we can't have a choice but to follow it. However, when it comes to the 
boundary of JS and Java, we are at a discretion to enforce slightly more 
explicit typing, should we choose to do so.

If we choose option 1 above, then your example will return true, but there will 
potentially be a lot of implicit toString() invocations on POJOs in code people 
write. We're somewhat wary of all those implicit toString()s.
If we choose option 2 above, then your example will throw TypeError and you 
will have to add an explicit .toString() invocation if you want to make it work.

While 1 seems convenient, note also that in other comparison cases JS would 
prescribe ToPrimitive() with a Number hint, and we couldn't really provide that 
either as POJOs are not readily convertible to a number, so we'd have a 
coercion that works for string comparison, but not for number comparison, 
which'd feel inconsistent. Consistently throwing TypeError would at the very 
least force the developer to acknowledge that you'll be doing a conversion 
here, and accept its costs as some toString()s are costly. Or even use a method 
other than toString() (which is really more meant to be a debugging method on 
Object anyway); also if you'd compare against a number, it'd make you decide 
what (if anything) is the number value of your object.

I'm throwing all this out here because we'd like to hear what the community 
thinks about which'd be the preferred way to go.

Attila.

On Feb 3, 2015, at 1:26 PM, Krause, Michael <[email protected]> wrote:

> Hi,
> 
> It seems that in Nashorn Java enums are no longer coerced into their string 
> value:
> 
> java.math.RoundingMode.UP == "UP"
> 
> evaluates to true in Java 7 but to false in Java 8 when executed in the 
> respective JavaScript engine.
> 
> 
> Does anybody know if this is actually a bug or just something in the 
> specification?
> 
> Thanks!
> 
> 
> 
> Mit freundlichen Grüßen / Best regards
> Michael Kurt Krause
> ________________________________________
> 
> Grazer Wechselseitige Versicherung AG
> Pestalozzistraße 73, 8011 Graz
> Tel.:    +43 316 908031-6174
> Fax:    +43 316 80379
> Mail:    [email protected]
> Web:    www.grawe.at
> 
> FN 37748m, Landes- als Handelsgericht Graz
> Bitte denken Sie an die Umwelt, bevor Sie dieses E-Mail ausdrucken!

Reply via email to