-
Notifications
You must be signed in to change notification settings - Fork 424
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
Should set.remove()
return the removed element?
#15819
Comments
@dlongnecke-cray - I'm not sure if you expressed an opinion for the answer to "Should |
Oh, good point. I think Do you know what happens to returned values that are not assigned in a multilocale context? Are they still potentially communicated across locales? This might be a separate issue at heart, but it might be reason enough to justify adding a method to |
Well, if |
I wrote the last sentence of my question wrong, edited for clarity ><. |
What will |
Well historically (based on what we've done for other such methods), we'd have it |
That makes me think I might prefer to stick with the current interface (which, as I understand it, returns On my first quick read of this issue, it seemed odd to me that in saying If we either used the If we had option types, we could have it return an option type value of course. We could also consider having |
I would prefer to introduce a method like Though I like the above names a bit more than |
I worry about having something as fundamental as Is there a precedent for |
I view it as a problem also shared by
It looks like the C++ |
What does "nicely" mean if the routine halts, though, when the value you thought was there isn't because someone else just removed it? I agree map.remove seems like it should share a similar design. list.pop() feels a little different because multiple things could pop simultaneously and both succeed... until the list becomes empty, I suppose. |
Part of me wants to say that I feel like a more general locking mechanism for containers in the spirit of #12306 could help solve this problem and others. We could also revisit the idea of having |
Halting for this seems untenable to me. Throwing would be fine, in my opinion.
I'm pretty sure we could get an option type together in short order, if we really wanted to.
I think the problem is worse for map.remove because with a map you'll remove based on the key but might want to get the value back. |
I'd still be inclined to leave |
If we want to throw then there are a whole lot of other cases where we currently halt that we might want to revisit. I'm fine with leaving things as is for now but I do think for |
Some notes from a Set deep-dive meeting today:
Names for throwing routine that returns the value:
Names for routine that just returns a bool:
Noted that:
|
I prefer For the future version that may or may not return an option type I'd be ok with proc ref remove(x: eltType): eltType throws;
proc ref drop(x: eltType): bool;
proc ref maybeRemove(x: eltType): Maybe(eltType); // Somewhere, in a galaxy one major version away |
|
That is a really beautiful idea, and one of the reasons why it appeals to me is that I've always imagined nilability to just be a very focused application of option types. My secret hope is that one day we could unify the two so that nilability is nothing more than syntactic sugar for |
I do worry that we might be overburdening the meaning/disambiguation of the |
I don't think we're anti-convention in our standard libraries (which is why we're putting in effort trying to unify on capitalization conventions, argument names, etc.). The issue with In contrast, in proposing this, I'm trying to come up with a convention which would pack some attractive options into a restricted namespace without requiring someone's favorite version of the routine to become to verbose / ugly (e.g.,
|
I like the idea of
I am not saying these are impossible to support at the same time - just that it is not already obvious to me how hard this would be in the parser. The Also, I am worried that combining with optional chaining (see #17577) will be confusing. Say you wanted to call a method on the removed element if there was one, with optional chaining. You would write |
Good point. I wasn't thinking carefully and was only thinking of |
Given the decision on #18649 to keep remove as is and support a different method for removing and returning, I'm closing this issue |
Currently
set.remove()
does not return the removed element at all, instead choosing to drop it on the floor. This choice was inspired by Python, whereset.remove
also returnsNone
instead of the removed value.Some of my reasoning for why Python's
set.remove
might returnNone
instead of the removed element:Chapel has value types (records) and reference types (classes) while Python only has reference types. In Chapel values added to a set are not required to be immutable. To achieve immutability without this requirement we make a copy of any element added to a set and only allow access to the set element by
const ref
.In addition to copying added elements, because users can overload the
==
operator for their types, this can create a scenario where two instances of a type (such as a record) evaluate as equal but contain significant differences.While one might argue that this is not overloading the
==
operator in good faith, that this can happen in practice suggests thatset.remove()
should return the removed value, -OR- at the very least we should add another method that returns the removed value such asremoveAndReturn
.The text was updated successfully, but these errors were encountered: