HaxeFoundation / HaxeManual

The official Haxe manual
https://haxe.org/manual/
Creative Commons Attribution 4.0 International
219 stars 154 forks source link

Specify equality #185

Closed raould closed 9 years ago

raould commented 9 years ago

I think we'd all benefit from and I'd love to see a concise ('just concise enough but no more'), coalesced set of docs that specify in as close to no-uncertain-terms as possible, how equality works in Haxe. This means how it works for all types vs. all other types, and across all supported back ends. (In addition, ideally there would already be a unit test suite that all back end implementations have to pass before being admitted to the shipping compiler suite, and those tests & the history of their pass/fail status would be a hyperlink away.)

Try to generate a lot of use cases so you can make sure the docs try to answer such issues. Some random ones I personally wonder about: Enum equality (see the old issue I raised years ago about it being inconsistent across platforms); String equality (cf. Java's == vs. dot-equals()); == vs. === (in ECMAScript ports).

Simn commented 9 years ago

IIRC the only exceptions are functions and enums with constructors (which are basically the same implementation-wise).

markknol commented 9 years ago

That sounds "just concise enough but no more" to me :smile:

raould commented 9 years ago

Thanks for the thoughts. I must be thick. Or you-all must have the compiler behaviour burned into your brains. Where are the specs for string equality (cf for the Java back end)? What about boxed-boxed vs. unboxed-unboxed equality testing? Where are the specs for how Haxe converts to JavaScript's == vs. ===? Etc. What if I need ===? etc. If I want to leverage any 3rd party {java,javascript,whatever} libs, how does one fit into that language's equality testing? Are such questions really answered clearly by Simn's kind of response for anybody who isn't a core Haxe dev? If/when bugs/misundersandings show up around this I won't even have the heart to say I told you so because my head will be broken from the brick wall it keeps hitting.

Simn commented 9 years ago

String, Int, Float and Bool as well as their boxed versions are compared by value, everything else is compared by reference.

ncannasse commented 9 years ago

@Simn I confirm the later statement, and we can add the following:

For enums:

Dynamic:

Could you add all of this to this page ? http://haxe.org/manual/types-numeric-operators.html

raould commented 9 years ago

Are there unit tests which show the old problem I ran into is gone / won't come back? http://old.haxe.org/ref/equality?version=14016

ncannasse commented 9 years ago

@raould if your assertEquals uses Dynamic, then it's platform specific. If OTOH you write the following you'll get a compiler error: withArg("a") == withArg("b")

raould commented 9 years ago

It sounds like this is the basic rules for when living in the rarefied air of being 100% Haxe code. Cool, thanks for updating the docs.

How does equality play with the underlying target platform e.g. for libraries? I don't understand what the whole Dynamic situation is. Does it mean there's nothing one can rely on with Dynamic re: equality testing? Does it mean it exactly follows the semantics of the target language? etc.

raould commented 9 years ago

Re: compiler error -- errrrrrrr, well, maybe there need to be more unit tests, then. Either that or what you wrote isn't (doesn't come across as) what you really mean, and the explanation needs some revising? The following test gives me "w merde!" and no compilation errors at all. Ubuntu 14.04 x86, Haxe 3.2.0. (At least now I get the assertion failure via cpp as well as neko & js, whereas it seems that back when, cpp did not fail it. So that's something better, at any rate.)

enum TestEnum { noArg; withArg(arg:String); } class Test { static function main() { var n1 = TestEnum.noArg; var n2 = TestEnum.noArg; if( n1 != n2 ) { throw( "n merde!" ); } var w1 = TestEnum.withArg("foo"); var w2 = TestEnum.withArg("bar"); if( w1 != w2 ) { throw( "w merde!" ); } } }

Simn commented 9 years ago

In the general case the compiler cannot detect that you are comparing enum values with constructors, so this is undefined behavior following the given limitation.

ncannasse commented 9 years ago

@raould you only get compilation error if you do w != withArg("foo"). If not, then it falls back to comparison by reference.

raould commented 9 years ago

I get the feeling I have to point out that the documentation needs to explain such things and explain them well. And that still I do not think it has been explained well in this thread. Since "you'll get a compiler error: withArg("a") == withArg("b")" seems like an incorrect or at least confusing statement to me vs. the test code I tried above.