-
Notifications
You must be signed in to change notification settings - Fork 426
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
How will map
support values of type non-nilable class?
#14861
Comments
Another option that just occurred to me is that we could keep the code as is and provide another overload for non-nilable classes: proc ref this(key: keyType) ref where isNonNilableClass(valType) {
compilerError("Non nilable class types cannot be default initialized. Use map.add instead");
} EDIT: Nope, no, this definitely wouldn't work...Didn't think that one through. But if there is a solution along those lines it might be better than just changing the semantics of |
Taking a bit more time to stew on this, I'm remembering that an approach I proposed awhile back is to have the associative array store nilable C when it's asked to store non-nilable C and then to take care of any casts from nilable to non-nilable in its implementation. |
It could (say) make
We still have to answer the question for what behavior we expect for the program @dlongnecke-cray showed above: use Map;
class Foo { var x: int = 0; }
var m: map(string, owned Foo);
m["key"] = new Foo(); So far it's been brought up that it could halt or throw. But there are completely different options available. Issue #14474 discusses changing |
So as @mppf and later @bradcray suggested (offline during lunch), I feel confident that judicious use of a proc ref this(k: keyType) ref where !isDefaultInitializable(valType) {
// Halt if the key is not in the map, else retrieve a ref to the value.
}
proc ref this(k: keyType ref {
// If the key is not present in the map, default initialize a value and add (key, value)...
// Else retrieve a ref to an existing value.
} This way we can get the best of both worlds. I didn't grasp what Michael was saying earlier, but I am really happy with this potential solution. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I was saying that we could change |
Prevent associative arrays and maps of non-nilable classes (#14846) This PR makes the initialization of associative arrays and maps of non-nilable classes a compile-time error. For associative arrays, this is accomplished by adding a `postinit` to the associative array subclass. For map, this is accomplished via use of a type routine. Associative arrays present a complication when the value type of the array is a non-nilable class. This is because a new key may be added to the domain of the associative array, causing a nil value to be default initialized. Additional constraints will have to be adopted for associative arrays of non-nilable classes to prevent this from happening. As for map, it should be possible to enable maps of non-nilable classes with some effort, see #14861. --- Testing: - [x] ALL on linux64 when CHPL_COMM=none - [x] ALL on linux64 when CHPL_COMM=gasnet --- Thanks to @daviditen for review!
Update! I'm having trouble casting a pragma "no doc"
proc const _getVal(key: keyType) ref: valType
where isNonNilableClass(valType) {
try! {
return vals[key];
}
} If I try to compile this I will get the following error:
Which is probably because the If I attach If this is not possible then it means that I feel like this should be possible but am not sure of how to achieve it. Ideas? |
@mppf / @vasslitvinov: Any thoughts? |
It's not possible today. This is related to #14307 and #8489. I don't think it would be easy to do. (It might make sense longer term, though). Also, my draft PR #14835 contains many Errors changes that are motivated by this issue (in subclass form, anyway). A similar question is - given a |
Ok, then. Back to the drawing board! What I need to figure out is an alternative way to use an associative array of non-nilable to implement |
I don't think that |
I view it as a stopgap as well, but w.r.t. to the current release schedule I think it is the only viable strategy short of continuing to ban maps of non-nilable classes. |
Since we currently do not support non-nilable associative arrays, it is reasonable to not support other resizable data structures with non-nilable elements. |
@vasslitvinov: The proposal here was that since (a) most operations on Personally, I'd prefer a @dlongnecke-cray: I'm not seeing the |
@bradcray, The
|
Earlier I said:
We now have issues #14937 and #14834 about the nilability and subclass downcast cases. However the result is the same - I think both of these features would break the type system and are totally unworkable. Responding to Brad's earlier comment:
This is what I think we should do. I think we should discuss it over in issue #14474. I think the main open question here is whether or not we need to change "the map" to not return references or whether we need to make multiple map implementations with different constraints. |
A third option is to just not support the A fourth idea would be to look into what Rust does (reportedly, they have a "slot" concept that's returned by such accessors that can be used to lazily insert something into the data structure?) |
@daviditen / @dlongnecke-cray: This can be closed now, right? |
Closing in favor of the discussion in #14474. |
This issue is made in the spirit of #14367 and #13602, which discuss the issue of supporting non-nilable value types for associative arrays and arrays, respectively.
Currently, the
map
type cannot support values of type non-nilable class. This is because (as far as I can see) of two reasons:proc ref this(k: keyType) ref;
which will implicitly insert the key to access into the map if it is not found, and then default initialize the value associated with the keyI think we ought to handle the second issue before we handle the first.
Originally, when designing the map API, @e-kayrakli suggested we have all overloads of
this
halt if the key to be accessed was not present in the map. Originally, I was against this because I thought it made use of a map less intuitive. However, clearly I did not have non-nilable classes in mind at the time.If we adopt the "halt if key not present" semantics for the ref overload of
map.this
now, then we can adjust the implementation of map to support non-nilable class values. Specifically:Following this
map
can safely support values of type non-nilable class, because key/value pairs may only be inserted together via a call tomap.add
.Thoughts?
The text was updated successfully, but these errors were encountered: