Am 01.02.2015 um 23:51 schrieb Aaron Meurer:
To be clear, I don't think that a Module class should necessarily subclass
an AbelianGroup class. Using subclasses to represent shared relationships
between mathematical objects is tricky.
It's usually impossible to do cleanly if the class offers ways to modify
its data. E.g. if you have a Rectangle class with a transform(matrix)
function that updates the Rectangle in-place, then there's no way to
make a clean Square subclass because it cannot uphold the contract for
transform().
If you avoid in-place updates (as SymPy does), that's not a problem.
> I personally don't think of every
module as being an Abelian group. I think of every module as containing an
Abelian group as part of its structure. Mathematically we might say a
module is a triple (R, M, *) where R is a unital ring, M is an Abelian
group, and *: R x M -> M is an operation satisfying some identities.
Agreed. Inheritance does not work well in this case.
I have spent quite some years toying with exactly this kind of problem,
and I now know for a fact that it's a relatively unique issue.
For Module, it would actually work; the real issues arise with Ring,
which is "twice a Monoid", once for + and once for *. This works fine
until you pass a Ring object to a function that expects a Monoid,
because the function won't know whether the caller meant to use + or *
for the Monoid operator.
The tricky part here is to judge whether one should favor composition or
inheritance; for Module, I don't know, there's no real reason to avoid
the inheritance because the multiplication is not even a Monoid, so
there's (probably) no room for confusion.
I'd probably still stick with composition, simply to be similar with
Ring. Similarities make it easier to think about the code, there's a
vague possibility that there might be a function that could work on both
structures (not so vague if Ring can be made into a subclass of Module,
I'd have to spend an hour validating that).
Then there's the question whether inheritance is buying us anything at
all. If no Group code ever reuses anything from Monoid, then yes it's
structurally nice to see the mathematical is-a relationship expressed in
the code, but we're just restricting what the subclass can do just to
conform with the design choices that made sense for the superclass.
From a programming perspective, I would expect an AbelianGroup object to
have a lot of methods on it that are very group theoretic, and it would be
distracting at best to have these methods all be inherited directly into a
Module object.
Yep.
There's one point that's still in favor of using subclasses wherever
possible: Serendipity. If you take the extra pain and put all the
structures into an inheritance hierarchy, somebody might be able to do
something extraordinary, whacky, novel, and useful with that.
I have no idea what that could be. It would be an attempt to create room
for invention, so others with a different mind for creativity can fill it.
That said, it would be some serious effort and a rather vague
usefulness. If the SymPy project is running at the limit of the effort
that its contributors can do, extra effort isn't available.
> I would rather expect to be able to do something like
M.as_abelian_group().some_group_theory_method.
That might be a circular argument - if that expectation follows from the
habit of favoring composition over inheritance.
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit
https://groups.google.com/d/msgid/sympy/54CF323A.40706%40durchholz.org.
For more options, visit https://groups.google.com/d/optout.