-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
RFC: Add generic copy stagedfunction for all types #9270
Conversation
I'm not comfortable with how this can silently produce the wrong results for types with a non-default constructor. It can also break abstractions; e.g. some types might be written under the assumption that no two instances share the same field values. I would feel a whole lot better if this were opt in. |
That's a good point; I think a default |
Agree with @toivoh this is very dangerous, a user defined constructor is not required to construct an object with fields that match its arguments. |
@mbauman could you explain a bit more about why |
@JeffBezanson Relates to #9170. A noop copy default would be wrong for matrices. |
Sure, it's just that Gadfly can sometimes mutate some of its aesthetics, and so it copies everything it doesn't know about by default. This can also be fixed within Gadfly, with But it seems to me that it's so trivial for immutable types to have a noop definition for |
A noop copy for immutables seems great, I think. |
Agreed. The question is simply what to do on the mutable branch since we can't restrict the
In reality, I think most mutable objects will also want to copy at least one of its fields (in base, I could only remove 2 of the 20 or so mutable methods due to this), so the utility provided here is probably not that great. Perhaps I should just change it to throw an error? |
Can't we just cheat construct the new object directly the way deserialization does? |
Yes, if we have a default @mbauman I find that behavior of gadfly very odd. Your description implies that it might mutate values it doesn't know about, which is hard to make sense of. It also sounds like the code mutates potentially-numberlike values. An alternative might be to wrap unknown values in 1-element mutable cells, or use a |
I'm actually in favor of having a default |
It might be ok, but one reason it might not is that copying just the outer struct seems unlikely to correspond to useful behavior. Needing to copy 2 levels (e.g. struct plus arrays it directly contains) is common. To @andreasnoack 's point, a struct-only copy is just as wrong for matrix types as a no-op copy. A no-op copy might have the advantage of being more obviously wrong. |
That's true. I guess that's one place where deepcopy is easier to reason about – you know you should copy all of the levels of the structure, so there's no ambiguity. |
It is a no-op for all immutable types, and for mutable types it instantiates a new object with the same fields; the fields are not copied.
Well, I've updated it to use the C API to cheat-construct the object. This is much better (it also now handles undefined fields and circular references), but I agree that its utility is still dubious in many cases. |
As far as why Gadfly tries to copy dates, to be honest, I'm not familiar enough with the implementation to give a more thorough answer. |
Even just copying the fields is dangerous, some things are not meant to be copied. Think about an int field that represents a file descriptor, if it is closed by one object, the other object now has an internal inconsistency. In general this can occur when a field relates to some external resource, eg pointers returned from C, if the memory is freed by one object the other object has a dangling pointer. Essentially with this addition every such type needs a @mbauman you would likely need to add lots of And all packages will also need to check their types for safe copying. And all user code. This is definitely a breaking change, not just a harmless convenience. And its not like the compiler can provide a deprecation warning or anything. |
Really, all I wanted to add is |
In the original gadfly issue I'd say the missing method error for copy did Maybe Date is another case where we'd want an abstract Atom type above |
What about |
No Number type should be mutable, even if its internal representation is. So |
If we had traits, we could capture |
@JeffBezanson. Right now, linear algebra with matrices of
(notice that the factorization is in-place) so from a performance perspective, it might be interesting to experiment with exploiting the mutability of |
That would be a great benchmark for #8699. |
I've seen |
OT: I was playing with a JuMP benchmark today that spent ≥50% of it's time in GC; I can distill it and put it somewhere useful if it's of interest. |
I'm closing this on the basis that just copying the outermost structure typically isn't what you want. |
It is a no-op for all immutable types, and tries to call the default constructor for mutable types. Fields are not copied.
Supersedes #9246; see that issue for some discussion of this.