2001 Enchancement Wishlist

Pearu Peterson pearu at cens.ioc.ee
Sun Dec 31 15:18:03 CET 2000

On Sun, 31 Dec 2000, Tim Peters wrote:

> [Pearu Peterson]
> > ...
> I bet it can't be handled that way in Python 42.0 either <0.41 wink>:  on
> the very face of it, the only *sensible* thing for a NonZeroInteger
> constructor to do when handed a 0 is to raise ValueError -- else its name
> lies about the nature of the thing it's constructing.
> Guido has Pronounced on this in the past:  a class constructor creates an
> instance of the class, end of story.  It's a little bit of semantics people
> can and do rely on.  For example, you didn't show any other methods of your
> NonZeroInteger class, but let's say it had a method xxx.  Then any Python
> programmer can rely on that
>     y = NonZeroInteger(anything_at_all)
>     y.xxx()
> won't blow up with an AttributeError on "xxx", and without doing dynamic
> type checks etc first.

Ok, the given NonZeroInteger was a bad example. I was quietly assuming
that whatever __init__ returns, has the same attribute set as
NonZeroInteger, that is, all these classes are derived from some parent
class (as you suggested also below).

Anyway, if __init__ returning is 'out', then what about class methods
that Gareth McCaughan suggested earlier. How 'out' or 'in' would that
solution be?

> There's nothing wrong with writing a factory function that can return
> objects of different classes.  It often makes code using them harder to work
> with, though, and precisely because you *don't* know what pops out of them
> in the absence of further type checks (however spelled).

I am willing to take that risk if it will reduce code considerably. It is
just a matter of whether a code developer is able to write consistent
code, whatever tricks are used.

> > c = Plus(a)           -> c = a          # c is Symbol instance
> >
> > ***lots of code*** could be avoided with rich Plus.__init__ that would
> > return in this case Symbol instance a.
> Wouldn't your "rich Plus.__init__" contain about as much code as a factory
> function would today?  Both have to consider all the same cases.  A factory
> function would get to omit the often-useless "self" argument, though <0.9
> wink>.

No. The code would be cleaner in various parts. And it would be also
faster. And all that because of there would be no need to bother whether
an object is in its minimal representation.
Examples of minimal representations:
        Plus(5) is mpz(5)
	Plus(a) is a
	Plus(a,b) is Plus(a,b)

> I suggest you're off track in your modeling, confounding roles that should
> be distinct:  that of Plus as a function and Plus as an object (representing
> an only partially evaluated sum).  In this case I'd probably have a base
> class Expression for all kinds of expresssions (incl. atoms like Symbols),
> make Plus a function mapping zero or more Expressions (or subclasses) to an
> Expression (or subclass), and make Sum a subclass of Expression that
> represents a partially evaluated sum.  

Yep. That's exactly how I have modeled it in PySymbolic (though with a bit
different naming convention but at least I am not too much off the

> That's the way I *think* of the
> domain, so that's the way I'd want to code it (and, no, I'm not bothered by
> having to come up with distinct names for the verb sense (Plus) and the noun
> sense (Sum) -- the distinction between nouns and verbs is usually helpful!).

Just for information:
There is a difference between Plus and Sum:
Plus - is a sum of Symbols, where the number of Symbols is
       *always defined and fixed*. E.g. Plus(a,b,c) is a+b+c
Sum  - is a sum of Symbols, where the number of Symbols is *not defined*,
       in general. E.g. Sum(n*n,n=[0,m]), where m is arbitrary integer.
And Plus will be used only internally in PySymbolic. Actually it just
represents operation symbol `+', not the verb `plus'.

> symbolic-math-would-be-useless-if-we-always-wanted-the-verb-
>     form<wink>-ly y'rs  - tim


More information about the Python-list mailing list