This post has two purposes: (1) I'd like to draw your attention to
#11115 (needing review), presenting a cythonized version of
cached_method. (2) I have a strategical question about applying #11115
in the category framework for rings - this may be better asked in sage-
algebra, which is therefore Cc.
(1) Features from #11115:
- @cached_method becomes a lot faster. If you do not provide arguments
by name but by position, then it is in fact faster than a hand-
written cache in Python (timings on the ticket). This also holds for
cached methods that a Python class inherits from the parent methods of
a category. So, @cached_method is now both convenient and efficient.
- If you have a Cython class derived from Parent or Element, then it
can inherit a cached method from its category, even if it does not
allow attribute assignment (previously, the cache was broken in that
situation).
- To some extent, cached_method can be used in Cython code. A hand-
written cache in Cython is still faster, but I guess cached_method is
more convenient in some situations.
For getting introspection and documentation right, one also needs
#9976.
(2)
The aim is to implement one- and twosided ideals of non-commutative
rings, also moving the whole ideal and quotient stuff from sage/rings/
ring.pyx to sage/categories.rings.py -- #11068.
There are non-commutative rings that do not and should not derive from
the base class sage.rings.ring.Ring, such as MatrixSpace(QQ,2): It
belongs to the category Rings(), but of course it shares its class
with other matrix spaces that aren't rings. In order to have a basic
implementation of ideals for such rings, it is convenient to provide
the necessary methods as parent methods in the category Rings().
The question in which I seek your advice:
(i) Should one duplicate the code from sage.rings.ring.Ring, so that
it *additionally* becomes available via Rings().parent_class?
(ii) Or should one move the code, so that it will *only* be available
via categories? It would require that all rings use the category
framework, but that is almost done (see #9944 and #9138).
The disadvantage of (i) is that duplication is known as a "code
smell", as I recently learnt.
The disadvantage of (ii) is that there are some methods, such as
zero_ideal, that currently use a hand-written cache in Cython. By
#11115, as a parent method of Rings(), zero_ideal could use
@cached_method, but that would be slower than the hand-written Cython
cache.
I guess it also depends on the kind of cached methods: How frequently
is zero_ideal() requested? If it is rarely used than a mild slow-down
wouldn't matter.
What do you recommend? Go for speed or avoid code duplication?
Best regards,
Simon