[Python-Dev] Re: PEP 326: A Case for All (original) (raw)

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