Am 11.03.2012 23:04, schrieb Ronan Lamy:
'Monoid' is a kind of structure, 'integer' is a kind of number. They
aren't on the same level.

Ah, agreed.

> But I agree that the name of a class should be
the (uppercase version of the) name designating an arbitrary instance of
the class, so the parallels are Integer/MonoidElement and Ring/Monoid.

Yes, except MonoidElement is a somewhat unwieldy name for a class.
Besides, the class defines Monoid axioms, so one could still argue that Monoid, if a category error, is still describing the purpose of the class well (but not the elements). Things get even unclearer if you consider that Monoid may be used for a symbolic math system (not SymPy, Python cannot fully handle diamond inheritance anyway). In such a situation, Monoid would probably also have functions that operate on the monoid itself, in which case one could argue that Monoid is really the better name.

Not that I'm actually arguing for any of these possibilities; it's pretty unclear to me what the best naming policy would be. Fortunately, the essay is about multiple inheritance, not about setting up a type hierarchy for math, so the whole issue isn't too important. Not in that context anyway :-)

However, there's another fundamental cause of confusion here.
Mathematically, a set and an algebraic structure over that set aren't
the same thing. If you call the set of integers ZZ, the ring of integers
is (ZZ, +, *), which "contains" 2 monoids: (ZZ, +) and (ZZ, *).

So, integers should be instances of the class Integer and we should,
separately, have an integer_ring object which is an instance of the
class Ring().

Yes, that construction would work.

> On the monoid side, things are a bit different because
MonoidElement is presumably a generic class that should work for any
monoid.

Ring would be generic, too, and just in the same way as Monoid.
The difference is that we don't need that genericity inside the current example, but we'd have a Ring<Integer,+,*>, a Ring<Vector<?>,+,*> (I'm being awfully sloppy here), etc.

> So, MonoidElement instances need a reference to the instance of
Monoid they belong to. To have integers fit with this generic framework,
we need a similar RingElement class, with signature RingElement(ring,
*params) and Integer should subclass it, so that Integer(n) is
Liskov-substitutable for RingElement(integer_ring, n).

Should work, too.
Not in Python, though. You still don't have the ability to inherit the Monoid operator twice into Ring and name it + for the additive monoid and * for the multiplicative monoid. Of course you could say that Ring is just a container for two Monoids, but it would become a bit cumbersome: when writing code that deals with a Monoid variable m, you'd be forced to write m.additive.op and m.multiplicative.op instead of m.plus and m.times. If you define m.plus as a new function that does m.multiplicative.op, you'll be unable to use a group polymorphically instead of a monoid.

Hmm. Okay. You can use the m.plus function where you know you're dealing with a Group, and m.additive to pass it to code that expects a Monoid. I'm not 100% sure that this will hold up in all situations, but it covers the most important cases anyway.

--
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to