On Thu, Jul 15, 2021 at 11:05 AM William Stein <[email protected]> wrote: > > On Thu, Jul 15, 2021 at 9:13 AM Nils Bruin <[email protected]> wrote: > > > > Following up: while sage's "RationalNumber" is indeed a numbers.Rational > > according to "isinstance", it does not actually adhere to the stated API: > > "numerator" and "denominator" are supposed to be properties, but in sage > > they are methods. So even in places where we are trying to fit into > > "Number" we are already failing. Changing the way that "numerator" and > > "denominator" behave would break a *LOT* of sage code. > > > I don't think we can do it. > > Dumb question, but right now:
In particular, thanks to Vincent Delecroix for pointing out that the answer is here https://trac.sagemath.org/ticket/28234#comment:7 In particular, @mcbell implemented exactly this for Sage over two years ago, and there is extensive discussion there about what happens. It's pretty crazy, e.g., "This now makes [instances of] the Sage Integer class callable and it appears that there are doctest that determine whether an object is an integer or not by testing whether it is callable!" William > > sage: n = 5 > sage: n() > TypeError: 'sage.rings.integer.Integer' object is not callable > > If we changed __call__ for integers to just return self, then maybe we > would have > > sage: n = 5 > sage: n() > 5 > > and this would mean that if we implemented numerator and denominator > as properties, then > > sage: a = 2/3 > sage: a.numerator > 2 > sage: a.numerator() > 2 > > would just work. Am I missing something? > > It's 100% my fault that numerator and denominator are function calls > instead of properties. Here's why I made that choice, both for > rational numbers and for a lot of other things. The reason is that I > watched lots of grad students struggling to use Sage/Python around > 2006 (e.g., at Arizona Winter School, in classes, etc.), and having > two different concepts -- methods *and* attributes -- with no easy way > to know which is which, just made things much more difficult for > people. People would do things like: > > sage: A = matrix(...) > sage: A.det > <built-in method det of > sage.matrix.matrix_integer_dense.Matrix_integer_dense object at > 0x7f7fca0c2ca0> > > and be like "WTF?", and I would explain "A.det is a function. You > have to call it.", and they woud then do > > sage: A.det() > number > > and think "OK, sage makes sense." If basically at random half of the > things listed in tab completion needed parens after them and half > didn't, that would confuse the hell out of my poor potential users. > And with Sage there is really no clear way to decide whether or not > something should be a property or a method, since it's really a > function of "how hard is it to compute? are there different inputs to > computing it?" The answer to the second question is unknown when you > write the thing, e.g., an input could be the algorithm or whether > proof is True. The thing that really convinced me was that > "A.det?" would give help on a number (not the det function) in IPython > back then at least -- well definitely "help(A.det)" would "not work" > at all in a helpful way. > > Please keep in mind that I made this choice over 15 years ago when > Sage had only a few users, and it would today have no users if I > hadn't made many design choices based on "what will confuse new users > less in 2005"... > > -- William > > > -- > William (http://wstein.org) -- William (http://wstein.org) -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/sage-devel/CACLE5GDEaz8SgZxPVP-mR7XBHS27vb33GdZoJCLH1RVG4gKk0g%40mail.gmail.com.
