-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHP 7 - Wrong Vector/Map/Set equality #67
Comments
@tyx we would need to implement
I'm guessing we'd iterate through both the table's keys and values and check if they're equal? (Or in the case of a Set, only the keys as all the values would be undefined).
Sorry about this annoying issue - keen to get it implemented and tested though. There's also the obvious win if the object being compared to is the same instance. ⚡️ |
Looks nice ! Thanks you for your fast answer.
Indeed !
Compared to the benefits we get to use your extension, it's not a big deal in fact ;)
Yes ! This one works actually |
@nikic would this actually be implicit if we implement the |
@rtheunissen Yes-ish. I'd assume you wouldn't want to have the same comparison semantics as a property comparison would give you. In particular, those would be weak and I doubt you'd want to have |
The only issue here is that we can't implement this in the polyfill. 🙅♂️ |
Only option would be to implement |
@rtheunissen ok so the main issue is equality so it's not a big issue about |
This is actually more difficult than I expected. For example, if we implement Or should we create an |
First of all, to me identity comparison (
Yes why not.
And yes why not, I'm not sure that it's needed but could be a nice to have. In fact I wonder about the way you want to proceed:
|
Yes I think so. Something similar to what lodash does with _.equals. We can fail fast with things like type and size comparisons. An interesting case would be a Map, which may not have the same ordering, but could be considered "equal".
No I don't think this is practical, better to just iterate through to compare. |
The issue remains that we can't implement a |
@rtheunissen yes ok for |
I'd like to keep them consistent, otherwise it invalidates the polyfill to some extent. Maybe if and when the extension becomes a default, we can drop the polyfill. |
Yes, can be a scheduled deprecation but you're right it's probably not the time to do that as it would break adoption. |
This change is actually quite complex. Whenever values are compared ( It's a shame that PHP still doesn't have a You can use something like |
We're are considering to replace our custom collection structures by DS, but we use collection comparisons heavily. Java defines specific strategies for computing hash codes for each type of collection. For maps, for instance, the hash code is order insensitive Our collection library has an
All methods should follow these rules, including Despite the issues related to the implementation of operation comparison overloading, it would be really helpful to have an About the Comparable RFC, it's an old discussion and I don't believe it will be added to the core anytime soon. |
That's true, but changing the behaviour of I agree that the collections should implement Hashable, and I think following the direction you've laid out makes sense. No need for the overloaded op just yet, that can come later. |
Constraining the roadmap according to a polyfill is a big mistake IMHO. The polyfill makes no sense for production use. For any other purpose, I believe that an IDE plugin or just stubs are the way to go. |
We have another problem. If we use the equality operator, then type juggling will break our plans. Furthermore, the operator |
|
How so? |
From the docs:
http://php.net/manual/en/language.operators.array.php
|
Ahh... well don't use arrays then. ;) |
It's not a choice. There is no way to constrain it in an application. |
I stand corrected, "the operator == is order insensitive in regards to arrays" https://3v4l.org/jdIBv |
Yeah, maybe the behavior changed in PHP 7 but the doc is outdated. Anyway, the major issue here is the type juggling.
? |
I think we should try to stay as close to arrays as possible. 😞
|
I personally don't use the operator
Stay close to array implies that order matters. About the equality relation, just close the eyes for arrays is a big inconsistency IMHO. Resolving this issue pushes this library to the next level 🚀 |
I thought we just agreed that arrays don't consider order important?
|
In the context of arrays, the order is relevant. For loose comparison, it is not. However, an |
Damn it, PHP. Not making this easy for us. 😠 But there's a solution here, just have to find it. |
How about storing arrays in the Map as Maps, transparently to the developer? When an array is put into a Map, it became immutable as you cannot pass it as a reference. Storing it as a Map allows us labeling it with a hash code which eliminates most part of the inequalities. For the other cases, we can use the comparison logic recursively, calling the |
Not a crazy idea, but I don't like the idea of putting an array in and getting a collection out. |
Let's just say that arrays use === comparison, end of story. If you need proper equality comparison, use a collection. or we can recursively descend into arrays and use the same equality checks. But that feels inconsistent and unexpected. |
This is why I said it should be handled transparently to the developer, so an array should be returned.
|
Here's the policy:
The third point here is the important one. We don't need to do anything clever or hacky to make this work, all we need to do is define the internal comparison behaviour. The only cost of doing this is that we can't support it in the polyfill, which supports the argument that the polyfill is not of practical value and should be abandoned. |
@rtheunissen 100% agree with you. Any chance of getting this working anytime soon? |
@marcospassos I don't want to release it under 1.x, but I could implement this and only this on a new branch? And merge that into 2.0 later on. But I have a lot on my plate at the moment so can't guarantee anything soon. Do you need |
Interesting to see the typical PHP issues that internals claims are no issues being discussed here. There are two kinds of relations between types, those that have a equivalence relation and those those with partial equivalence relations. This also matches what proper programming languages actually provide (e.g. Rust). The thing regarding order is actually very simple from a math point of view. Two collections (set, map, …) are equal if they contain the same elements, regardless of order. This is why every proper language provides different types for e.g. set and sorted set as well as map and sorted map. Another thing that is very important to understand is that equality is not covered by comparability. The same ordering of something does not directly translate to equality. I explained this once in internals but the best and easiest example is infinity. Infinity is not smaller nor greater than infinity, however, infinity does not equal infinity.
There are more examples with date and time but I think this is sufficient as an explanation. Also, just for your consideration, providing methods to call is faster than overloading the operators (a lot if you have many comparisons). I benchmarked this once with a C implementation where I allowed overloading for all operators with marker interface as the ones I showed here. PS: Sticking to what PHP already does might seem like a good idea from a familarity point of view. Doing so also means that it is, well, mostly wrong. PPS: Note that there are also totally ordered sets and partially ordered sets, however, this discussion is about equivalence relations only so I did not include it. |
Coming back to the plan of action for 2.0 here:
Consequences:
|
Hi everyone. 👋 My plan for comparison behavior in 2.0:
|
@rtheunissen this is the right decision to me. I've abandoned this extension because of this kind of issues and honestly if all of that is because of the polyfill kill it! |
It's such a shame to abandon the polyfill. |
I think creating a different issue from #65 is a better idea.
Current problem
it makes me very sad as I definitively can't rely on Ds in my tests. And I use
Ds
everywhere as it does a really nice job (thanks for that anyway)Solution
Is there any reason why this behavior ? And is it a bug or a known behavior ? Looks too big that anyone complain about it ^^
Whatever I'm definitively open to contribute event if my C skill are very old because it cannot stay like that.
I already had a look on the (clean) code.
I guess we need to implements the compare_objects handlers on the internal htable ? Looks pretty obvious, I know. May be we can even use the
toArray
and rely onarray::compare_objects
?Is there any stuff that prevent us to do that ?
Anyway, let me know what I can do to help on this very annoying issue.
Thanks
The text was updated successfully, but these errors were encountered: