-
Notifications
You must be signed in to change notification settings - Fork 847
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
2.15.17 introduces changes in equality #2147
Comments
This behavior change was intended. "a" and "b" in your examples aren't technically equal:
Is there a reason your use-case requires |
This is, I think, probably more directly related to how Scala handles the return of null from the
In Scala I can't check if "attributes" is really null or just an empty Map. Given that I can't obey the identity law of lenses or "set what you get". I might be able to use hasAttributes as a proxy for checking if it's really null assuming it's consistent as most of the project is generated by macros though passing null (which is avoided and discouraged in Scala) to some functions wouldn't easily work if there are overloads. |
It's not just a Scala limitation - it's the same in Java. If you need to see if the response from the service was null or an empty map, the We default to empty map even for null map responses from the service, because most of the time the distinction isn't useful, and every service does something a little bit different. Customers kept getting NPEs when we would return null for maps, so we decided to always return an empty map, and if the customer actually cared about the distinction (e.g. union types like DynamoDB's AttributeValue) they could use the has* method. It's also worth noting that most update* APIs do not require you to pass in the entire "current state" of the resource, just what you want to modify. If you don't specify a value for a specific field, most services will keep that field unmodified. |
I was able to update the code to use has* and pass a null explicitly. It's not that the entire state of the object must be passed, simply that what you get and what you set are the same and representation shouldn't change by passing back in what you just got. These objects don't technically do that because you get an empty Map and then when you set an empty Map the object's representation changes. Lenses have to not change the representation in any unintended way to make them compose-able. Basically information is lost coming back out of the "get" function. Set(null, EmptyMap, Values) => Set(EmptyMap, Values) |
Yeah, I agree that set(null) and then get() returning an empty map is a point of confusion. That's always existed, though, even before the equals method was updated in the PR above. It was a trade-off we made because a lot of customers found it confusing that some services would return null, and some would return empty lists. They would either have to do null checks all of the time or risk getting NPEs. When they asked us what the difference was, we had to admit that "different services do different stuff, so I don't know, just do a null check every time to be safe". We introduced this confusion because it was less confusing and affected fewer developers than what we used to do: just expose whatever the heck the service wanted to do. |
Thanks for your help. I hadn't really paid attention to the has* functions as check to recover that info. That solves my issue. |
…ccd28d67f Pull request: release <- staging/97fa5cab-d98d-4a93-a3f6-275ccd28d67f
In 2.15.17 a change was made in PR #2119 that makes two objects no longer equal that were previously equal due to how maps and lists are handled.
Prior to 2.15.17
a
andb
are equal. (2.15.16)2.15.17 and after
a
andb
are no longer equal (2.15.29)As far as I know these should still be equivalent. I maintain a library of lenses for AWS using Scala/Monocle and this breaks some of the laws required of the lenses. If this isn't considered a bug I'd like to know so I can decide if I will continue trying to maintain the library.
The text was updated successfully, but these errors were encountered: