On Wed, Jun 11, 2014 at 12:42 AM, Marc Mezzarobba <m...@mezzarobba.net> wrote: > Robert Bradshaw wrote: >> So you would prefer >> >> sage: 4/2 == 2 >> False >> sage: 4/2 + 0/1 == 2 + 0/1 >> True > > Definitely. > >> sage: R.<x> == ZZ[] >> sage: (x-1) * (x+1) - x^2 + 1 == 0 >> False > > I certainly agree that being able to use "== 0" here is convenient. > > But having to write, say, eq(pol, 0) instead does not seem too high a > price for consistency with the assumptions Python makes on equality. (Do > not misunderstand me: if Sage had its own language, I would prefer to > use == for the richest form of equality, and some other notation for the > version consistent with hashing.)
In Python, 2 == 2.0 returns True. Sage simply has a richer number system, but what we do is more consistent with Python than requiring objects to be the same type/parent to compare equal. > And IMHO your examples are not worse than > > sage: x = SR.var('x') > sage: bool(arctan(1+abs(x)) == pi/2 - arctan(1/(1+abs(x)))) > False Better returning True when the CAS isn't strong enough to prove equality (which may well be most of the time). > sage: R.<y> = QQ[] > sage: R(0) == GF(2)(0) > False Yeah, that's sub-optimal. I've actually thought for a while it might make sense to use the pullback rather than pushforward as a common parent in which to do comparisons. That would make sage: RR(pi) == pi False sage: RealField(10)(pi) == RealField(100)(pi) False but I do find sage: GF(5)(-1) == -1 True sage: Qp(5)(-1) == -1 True to be handy (though might be worth sacrificing). > sage: R(0) == 0 and 0 == GF(2)(0) > True > > sage: {t.parent() for t in {R(42), 42}} > {Integer Ring} > sage: {t.parent() for t in {42, R(42)}} > {Univariate Polynomial Ring in y over Rational Field} Totally, just like Python's {type(t) for t in {0, 0.0}} == {float} Can you think of any reason you'd want to do this? > sage: {42, QQbar(42)} > {42, 42} > sage: {42, SR(42)} > {42} > sage: {2^100, SR(2^100)} > {1267650600228229401496703205376, 1267650600228229401496703205376} Hash is not as good as it could/should be for large symbolic integers. And for AA/QQbar. > sage: eq = SR(GF(2)(0)) == SR(2); eq > 0 == 2 > sage: bool(eq) > True Yeah, SR is weird. Especially with elements that don't embed into CC. >> Note also that if GF(p)(1) != 1 != >> int(1) and is not an error then trivial looking code like >> >> def order(a, p): >> """ return x such that a^x == p, naively """ >> if a == 0: >> return infinity >> else: >> x = GF(p)(a) >> count = 1 >> while x != 1: >> x *= a >> count += 1 >> return count >> >> has a really bad bug in it. > > Not that bad if x != 1 throws an exception. Besides, Java programmers > have had a similar problem forever and can apparently live with it... Yeah, and considered one of Java's big pitfalls, though when your language doesn't allow operator overloading I suppose that's consistent. I might be OK with throwing an exception between really incomparable elements, but marring equality to blindly abide by hash's standards isn't the right thing to do IMHO. A (bad) alternative would be to define class Element: def __hash__(self): try: return hash(float(self)) except: return 5077 Also, I think the typical usecase of objects being used as keys, including in cached_method, is for objects of the same (or similar) type. -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.