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
Make Java Map
wrappers handle nulls according to put
/remove
contract
#9344
Conversation
any collections-crew opinions here? @Ichoran @NthPortal @joshlemer — we should make a team for y'all for easy @-mentioning |
LGTM. If we are content with not passing on every call to
But the change to the logic is good either way. |
In my cut and pastey haste, I forgot my previous point that, if there's a race, checking |
The |
And just for completeness, there is another place where this could be changed: This may in theory be the case, as the java concurrent maps explicitly (by a comment) allow maps handling If we would change this, every call of What do you guys think? |
Not sure if that is better. Maybe def get(k: K) = {
// Assume k is not (yet) in the map
val v = underlying get k
// What if, here, between these lines, another thread puts a value for key k in the map?
if (v != null)
Some(v)
else if (underlying containsKey k)
Some(null.asInstanceOf[V])
else
None
} If another thread puts a value between the calls of |
Right, something like I'll spend a few minutes with the issue of other methods, thanks for your comment. I did spend a few minutes with Hashtable and Properties. In a way, it's nice to spend time with API I never use any more. |
Maps cannot be safely used concurrently, so I wouldn't worry about that too much. The logic just needs to be right for non-concurrent access. (Unless it's a map that guarantees correct operation during concurrency.) |
They could have a footgun app where instead of With a 48 hour cooling off period! |
import scala.jdk.CollectionConversers._ |
created https://github.com/orgs/scala/teams/collections/members @-mention as @scala/collections happy to add anyone else — I tend to assume that other folks like @som-snytt and the team here at Lightbend see everything anyway |
I don't like it—in fact, I hate it—but I agree that it's probably the best solution |
If map contains key, always return nonEmpty. If binding to null, return Some(null) instead of None. This behavior is consistent with get, which is the basis for getOrElse, lift, and unapply.
Pushed Ichoran's tweek. (Visual pun alert on geek.) I reviewed ansvonwa's comment about whether more is desirable, especially in light of Ichoran's comment about concurrency. My conclusion is that, as a convenience feature, it's enough to 1. ignore concurrency in the normal wrapper and 2. assume JDK implementations in the concurrent case, where null keys and values are disallowed. I added a comment that consistency with get is the desideratum, because get is the basis for getOrElse, life, and unapply. That means A map of boxed Double with a null value will unbox to 0.0. |
You can't compute a null value, but you can put it. I probably won't push this change. Tired of waiting for the green check on the current PR. |
This is still needs a review. @Ichoran or anyone in @scala/collections care to look at this, please? |
okay... somebody else want to adopt this? |
I'm not really around enough to reliably review things any more. I agree that this is the way to do it--it's a good implementation if we think that a double-lookup is worth it for correctness. For what it's worth, Java itself decided it wasn't; all the methods added for JDK 8 treated mapping to null the same as no mapping. I don't use wrapped Java maps personally, though, so I don't have a strong opinion either way. So, if someone decides we want this, then it can go in as is, no changes needed. If we decide we don't, then there's nothing to do. |
thanks, Rex. we will still welcome your reviews if/when we can get them — but, noted that we shouldn't wait around too long if we haven't heard from you. |
I'm in favor of this change as it makes |
Map
wrappers respect put
/remove
contract
Map
wrappers respect put
/remove
contractMap
wrappers handle nulls according to put
/remove
contract
If map contains key, always return nonEmpty.
If binding to null, return Some(null) instead of None.
Fixes scala/bug#11894
The text was updated successfully, but these errors were encountered: