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
InheritComparisonUniqueRepresentation #25388
Comments
comment:2
My first reaction is that it doesn't really make sense to use |
comment:3
Perhaps the entire concept is wrong somehow? That said as you can see there are cases of this (albeit with classes that only inherit Why doesn't it make sense? Just as Alternatively, it would be nice to have something that behaves somewhat like |
comment:4
In any case, it does make sense, as long as we have a complicated metaclass hierarchy, to have a metaclass that combines |
comment:5
I can think of certain morphisms that I could see benefiting from being |
comment:6
There are a couple of reasons why
The reason why we have That's why people think it's strange to make elements |
comment:7
That's weird about the memory leaks since I thought the point of using weak reference caching was that you could construct an object once--it would be cached--but then if it isn't used again the cached keys would (potentially) go away. As for this specific ticket, perhaps the use case of using However, my primary motivation to using more If |
comment:8
Replying to @tscrim:
On that note, could you have a look at #25389 and tell me if the use of |
comment:9
Replying to @embray:
That's true, but the caching is not the primary design feature. It's a cost more than a benefit (but necessary for what it does). The global cache brings you very close to creating a global anchor for reference cycles: The global weakvaluedict that does the caching has strong references to the keys used (the construction parameters). As has been shown time and again, these keys have a tendency of carrying references to the cached object. Now your memory cycle is globally anchored and will be immune to cyclic garbage collection: a memory leak. This kind of leak keeps occurring. See #23807 comment:14 for a recent example. The |
comment:10
Replying to @embray:
The construction parameters of quaternionalgebras are sufficiently light that I would not expect memory leaks (as long as people don't take to caching quaternion algebras on the base ring!, which now that I thought of it, people will undoubtedly start doing). In principle, I would find it surprising if people are actually doing that with quaternion algebras, so I don't think we're getting the designed benefit from quaternion algebras. By turning quaternion algebras into globally unique objects, you are requiring the algebras to be immutable in a very strong sense: different parts could end up having references to the same algebra, so ANY change in state (even little representation/caching details) must be assumed to affect completely unrelated code. It's not possible to make your own little local algebra and scribble in it anymore. More precisely. The kind of scenario in the coercion framework where I know that
Note that the coercion framework needs to construct a common covering parent for |
comment:11
Replying to @nbruin:
While I like the feature of Having an additional, usually small, tuple of references is not generally a major memory concern but of course as with anything it depends on how many of these objects you expect to construct. |
comment:12
Replying to @nbruin:
Thanks for looking at it and for the explanation. I agree. I guess what I really just want there is the aforementioned |
comment:13
I believe this issue can reasonably be addressed for Sage 8.4. |
comment:14
I think this utility class is still useful as it clearly makes a few minor simplifications. |
comment:15
The problem is that I'm still not convinced that combining |
comment:16
Oh what basis? On its face there's no reason not to and there are clearly classes that do use that combination. Now, if you disagreed that those classes should be using that combination in the first place that's another story: If those were fixed then there would be no use for adding this class. But first you'd have to justify why those classes shouldn't use |
comment:17
Looking at the code referenced in your commits: Indeed, it looks to me these objects have no business being It could be that those pieces of code are from before |
comment:18
So I can answer for This does not quite hold as much water for |
comment:19
Replying to @tscrim:
I see you make an argument for why However, it seems that the comparison and hashing you want is NOT the one from Be careful with thinking that |
comment:20
So should On another note, I'm not even convinced |
comment:21
Replying to @embray:
I think that is because it actually pokes around in the class data structure, to "hard" inherit the slot value for the comparison functions, the way it would happen normally. The difference is that normally, comparison is not inherited if the hash is changed. The |
comment:22
Ah, I just tried to implement it as a decorator and the problem is actually that Cython will not allow you to use "arbitrary" class decorators on cdef classes. Which is a shame because I don't see any reason that couldn't work. Yes, it is dangerous, but consenting adults and all... What's worse is, it still works just fine if you call it not as a decorator, but just at module-level after the class definition (note: I defined a Python function called
So I don't think it needs to be a decorator. At the same time, as I wrote previously, I suppose the advantage of using a metaclass is that the behavior will automatically be inherited by subclasses, whereas with a decorator (whether used as above, or with the actual decorator syntax) one has to remember to use it when subclassing. So in light of that, having the metaclass makes sense, unfortunately. One bit of good news is that Python 3 (specifically 3.6+) has added a number of new dunder methods for customizing class creation that ease many of the most common use cases for metaclasses without explicitly using a metaclass. For example, I think init_subclass might be able to serve as a replacement for |
comment:26
Moving tickets from the Sage 8.8 milestone that have been actively worked on in the last six months to the next release milestone (optimistically). |
comment:27
Ticket retargeted after milestone closed |
comment:28
Batch modifying tickets that will likely not be ready for 9.1, based on a review of the ticket title, branch/review status, and last modification date. |
comment:30
red branch => needs work |
comment:31
Setting new milestone based on a cursory review of ticket status, priority, and last modification date. |
comment:32
Setting a new milestone for this ticket based on a cursory review. |
This is a bit ugly, but it seems to be necessary if you want to use
UniqueRepresentation
with subclasses ofElement
(among others) which has theInheritComparison
metaclass. This otherwise creates a conflict withClasscallMetaclass
.This class resolves that by making a
UniqueRepresentation
with theInheritComparisonClasscallMetaclass
. This can then be used as a mix-in class withElement
subclasses.There's at least some prior precedence for this, and I've updated those examples to use
InheritComparisonUniqueRepresentation
to demonstrate that it works. I'm open to better ideas.CC: @jdemeyer
Component: refactoring
Author: Erik Bray
Branch/Commit: u/embray/misc/inherit-comp-unique-repr @
8d665aa
Issue created by migration from https://trac.sagemath.org/ticket/25388
The text was updated successfully, but these errors were encountered: