On Tue, Mar 10, 2009 at 06:27:41PM -0700, Robert Bradshaw wrote: > Currently the rule is that if you can do arithmetic between two > elements, you can compare them.
Ok, I am not used to it, but this seems fair enough. > Membership code is something entirely different. > > > I typically write things like: > > > > class MyParent > > def bla(self, x) > > assert x in self > > ... > > > > I really mean that x should be an element of self; not something that > > could be converted into it. > > Membership is much more lenient than coercion, for example, I would > be more worried if the following returned False > > sage: 4/2 in ZZ > True Good example. Yes, finding the right balance is tricky (in MuPAD 4/2 *was* an integer). I guess it all boils down to what are the convention for membership testing, and how much freedom one has in implementing it. Here are some typical options: (1) x is in P if there is an element of P that is equal to x under == or if x is already an element of self (this is the doc of __contains__ in Parent; is this a fixed rule engraved in the marble for every Parent?) (2) x is in P if P(x) raises no error (this is the current default implementation in Parent) (3) x is in P if it can be coerced into P (which could be implemented by just testing for the existence of a coercion, without actually applying it). (4) x is in P if x.parent() = P (1) is non trivial to implement. In principle, the __contains__ function of ZZ should be able to handle all parents, now and in the future, into which there is a natural embedding of ZZ. (2) seems completely off balance to me. Being able to construct a P from some data does not convey any mathematical link between that data and P. (3) sounds reasonable, at least as a widely used default implementation. And possibly with a couple well marked exceptions for the really common cases like 4/2 in ZZ, to be introduced on a case by case basis when really it feels unnatural without them. I personally lean for (4), but am ready to call myself an extremist on this one. > > Just yesterday, I lost 1 hour around this because membership testing > > for a Weyl group ultimately led to listing all the elements of the > > group. Which is problematic for an infinite group. And it was not easy > > to straighten this up cleanly. > > I'm not sure how a more stringent default "in" or comparison operator > would have helped here. It's a long a story. But to make it short, with option (3) and with some more stringent conversion rules, Sage would not have tried to convert my WeylGroup(["A", 4]) element into a matrix and then into W= WeylGroup(["A", 3, 1]) to finally compare it with all elements of W. > > In short: for < = in, if it was just me, I would only use the most > > absolutely trivial coercions. And in particular avoid there all the > > coercions that involve projections and not embedding (like Z -> Z/nZ) > I would like to avoid having a whole hierarchy of coercions, some of > which are used in some cases, others in other cases. People have > enough trouble understanding the system as it is. I definitely see your point. Well, without introducing a hierarchy, there is this natural notion of invertible coercions (strongly connected components in the conversion graph). But that would not have helped anyway for 4/2 in ZZ. Here it's more about a notion of partial inverse for the canonical coercion from ZZ into QQ. It probably would be over engineering to introduce it. Cheers, Nicolas -- Nicolas M. ThiƩry "Isil" <nthi...@users.sf.net> http://Nicolas.Thiery.name/ --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to sage-devel-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~----------~----~----~----~------~----~------~--~---