[Python-Dev] Re: PEP 326: A Case for All

Phillip J. Eby pje at telecommunity.com
Sun Jan 4 22:32:51 EST 2004


At 04:29 PM 1/4/04 -0800, Josiah Carlson wrote:
>Just because something is simple in idea and implementation, doesn't
>mean that it shouldn't be included with Python.  The entire itertools
>module is filled with very useful functions that are simple in idea and
>implementation.

And they're not built-ins, either.


>The introduction of All into Python would offer users the opportunity to
>use an always-compatible implementation of All, without the
>arbitrariness of argument placement during comparisons:
>
> >>> class _AllType(object):
>...     def __cmp__(self, other):
>...         if isinstance(other, self.__class__):
>...             return 0
>...         return 1
>...     def __repr__(self):
>...         return 'All'
>...
> >>> class _AllType2(object):
>...     def __cmp__(self, other):
>...         if isinstance(other, self.__class__):
>...             return 0
>...         return 1
>...     def __repr__(self):
>...         return 'All2'
>...
> >>> All = _AllType()
> >>> All2 = _AllType2()
> >>> All > All2
>1
> >>> All2 > All
>1

Can you show how/why this is a problem, or is likely to be a problem?

The point of not putting simple things into the standard library isn't 
whether they're simple, it's whether enough people (or standard library 
modules) need to do it, and if there are relatively few people who need to 
do it, and they *can* do it, why not let them do it themselves?

The examples you keep presenting aren't motivating in themselves.  If I 
agreed with you that it was a widely-needed and useful object, the content 
of your PEP (apart from the Motivation section) would be helpful and 
informative.  But the PEP provides no real motivation, except a repeated 
assertion that some set of algorithms would be clearer with its use.


> > The "Motivation" section of PEP 326 does not answer this
> > question.  Although it claims "hundreds of algorithms", it demonstrates
> > only *one*: finding the minimum of a sequence.
>
>I should have probably made it more explicit.  The most visible change
>when using All, in cases where a logical infinity was needed, is the
>removal of some "or (cur is None)" blobs.

Perhaps I should've made my point more explicit.  I find it clearer and 
more efficient for "find a minimum" to take a value from the items under 
consideration, than to construct an artificial starting point.

That's the only algorithm you presented, so it's the only one I could 
reasonably comment on.


>The next most visible change
>is the increase in understandability of some algorithms who require an
>infinity initialization.

Please illustrate some that would be commonly used, and not better off as 
say, part of a graph algorithms library.  (In the latter case, such a 
library could certainly provide its own logical infinity implementation, 
specifically suited to the use cases involved.)


>I offered the finding the minimum code in order to offer an easily
>understood algorithm that is simplified by All's introduction.

But it's not a *motivating* example, because the problem you presented is 
trivially solved using min(), slicing, or iterators.


>If you
>would like, I'll put together some code that solves various graph
>algorithm problems, use 'All', and are simplified because of it.  I did
>not post any in the PEP because I believed that the implications of All
>were straightforward.

The implications are straightforward enough.  The motivation for a builtin 
is not.  Based on the discussion so far, it seems to me that this is 
something that belongs in e.g. the Python Cookbook, or part of a graph 
processing library if there are lots of graph algorithms that need it.

So far, you haven't mentioned anything but graph algorithms; are there 
other common applications of this object?  What are they?

Without *concrete* use cases, it's impossible to validate the design.  Over 
the course of these threads, you've asserted various invariants you expect 
All to meet.  These invariants are not documented in the PEP (except 
implicitly in the implementation), nor are their reasoning explained.

But, since the only use case you've given is reimplementing 'min', how can 
anyone say if the invariants you've asserted are the correct ones for the 
intended uses?  For example, why must All compare equal to other instances 
of its type?  It's certainly not necessary for the reimplementing 
'min'.  Should it even be allowable to create more than one instance of the 
type?

How can we know the answers to these questions without actual use 
cases?  We can only answer YAGNI, and wait for libraries to pop up where 
people actually use a logical infinity object.  When they do, we'll either 
find that: 1) the invariants they use are the same, possibly justifying an 
addition to Python, or 2) the invariants they use are necessarily 
different, meaning there's no reason to pick one arbitrarily.


>"All" isn't about how many different ways there are to find the minimum
>of a sequence.  "All" is about having a useful and consistant constant.

Useful to whom, for what?  That is the question that isn't even touched on 
in your PEP, apart from the "minimum of a sequence" example.

By the way, with regards to your references section, it might be a good 
idea to include this one:

http://mail.python.org/pipermail/python-dev/2003-December/041332.html

whose last paragraph goes to the point I'm making about choosing invariants 
based on actual use cases.




More information about the Python-Dev mailing list