[Edu-sig] computer algebra

kirby urner kirby.urner at gmail.com
Thu Dec 11 03:47:36 CET 2008

```So I've been yakking with Ian (tizard.stanford.edu) re the new
fractions.py, installed in Standard Library per 2.6, saw it demoed at
a recent user group meeting (PPUG).

Python's __div__ is similar to Mathematica's computer algebra notion
of division in that you're free to divide any type by any type,
providing this makes any algebraic sense, using a kind of liberal duck
typing.

What I mean by that is __div__ by itself doesn't pre-specify anything,
so if there's a meaningful way to deploy the division operator between
arguments A, B, then go ahead and do it, write you code accordingly.

In Java, we could write __div__ in all different ways depending on
stricter typing at write time means you've gotta post "guards at the
gate" in your methods).  Python, with late binding, duck typing, won't
post guards, but you'll still need to write algorithms capable of
sorting out the possibilities.  Maybe the user throws you a matrix?
Has an inverse.  OK, so __div__ makes some sense...

fractions.py in contrast, implements the narrow Q type, the rational
number, defined as p / q where p, q are members of the set integers.

One could imagine a Fraction class that eats two complex numbers, or
two Decimals.  Computer algebra attaches meaning here, as in both sets
we're able to define a multiplicative identity such that A / B means A
* B**(-1) i.e. A * pow(B, -1) i.e. A * (1/B).

So the results of this operation, Fraction(A, B), might be some object
holding the Decimal or Complex result.  In generic algebra,
everything's a duck, although conversion between types is possible
(yes, that sounds nonsensical).

fractions.Fraction, on the other hand, barfs on anything but integers,
isn't trying to be all divisions to all possible types, isn't
pretending this is Mathematica or a generic CAS.

Note that I'm not criticizing fractions.py in any way, am so far quite
happy with it.  I'm simply drawing attention to some fine points.

Related:

When I went to all the trouble to compose two functions, f and g,
using __mul__, I'd get comments like:  but the "open oh" (another
symbol) is the "composition operator" i.e. "you're only using *
because ASCII doesn't include the 'open oh'".

However, I was making a different point:  that in group theory math
texts, we're proud to use "regular" multiplication and division
operators for such operations as "compositions of functions" because
we're thinking __mul__ and __div__ have that generic meaning -- we
neither need, nor want, the proliferation of symbols the "open oh"
people think we must need.

Note that by "open oh" I'm not talking about "big oh", a different
notation that I don't think is redundant, agree with Knuth that if
your calculus book doesn't include it, you're probably in one of those
computer illiterate schools (ETS slave, whatever).

Kirby
```