[Python-Dev] Re: PEP 326 now online

Gustavo Niemeyer niemeyer at conectiva.com
Mon Jan 26 15:31:22 EST 2004


[...]
> The only question is where is a location we can put them without
> polluting a random namespace with objects that don't fit.  Math is out
> (Min and Max aren't floating point numbers, which you can read more
> about in the PEP), cmp.Min/Max are awkward, min.Min and max.Max seem
> strange, operator.Min/Max seems like a reasonable location, but no one
> has any feedback on that one yet.  Again, I'm open for suggestions.

My suggestion is to not introduce these objects at all, and if they're
going to be introduced, there should be internal support for them in the
interpreter, or they're meaningless. Every object with a custom cmp
method would have to take care not to be greater than your objects.

> > > Arguably, there aren't any usage cases where None is necessary.  But yet
> > > we have None.
> > [...]
> > 
> > Please, let's not ignore how these usage cases differ in wideness.
> 
> Imagine for a moment that None didn't exist.  You could create a
> singleton instance of an object that represents the same idea as None
> and make its boolean false. It would take <10 lines, and do /everything/
> that None does.
[...]

Please, let's not ignore how these usage cases differ in wideness.

> Take a look at the first few examples in the 'Max Examples' section of
> the PEP: http://www.python.org/peps/pep-0326.html#max-examples
> Notice the reduction in code from using only numbers, to using None, to
> using Max?  Notice how each implementation got clearer?  That is what
> the PEP is about, making code clearer.

Comments about the "Max Examples":

- If the objects in the sequence implement their own cmp operator, you
  can't be sure your example will work. That turns these structures
  (call them as you want) into something useless.

- "Max" is a possible return from this function. It means the code using
  your "findmin_Max" will have to "if foo == Max" somewhere, so it kills
  your argument of less code as well.

[...]
> An even better question would be, "How would two objects with __cmp__
> react?"  Checking a few examples, it is whoever is on the left side of
> the comparison operator.

Exactly. That's the point. Your "Top" value is not really "Top", unless
every object with custom comparison methods take care about it.

[...]
> The entire itertools module is filled with examples where just a few
> lines of code can save time and effort in re-coding something that
> should be there in the first place.  The PEP argues the case that a
> minimum and maximum value should be placed somewhere accessable.

Understood.

> As stated in the PEP:
> "Independent implementations of the Min/Max concept by users desiring
> such functionality are not likely to be compatible, and certainly will
> produce inconsistent orderings.  The following examples seek to show how
> inconsistent they can be."  (read the PEP for the examples)

Independent implementations are not compatible for the same reason why
your implementation is not compatible with the rest of the world. IOW,
an indepent implementation would not respect your Max, just like any
object with a custom comparison may not respect it.

[...]
> The only thing you've "presented" so far is that you think that the
> objects are fundamentally useless.  On the other hand, no less than 10

Sorry, but you're blind. Review my messages.

> people here on python-dev and c.l.py (I didn't even announce it there)
> have voiced that the objects themselves are useful if given a proper
> name and location.

The fact that other people agree with your suggestion doesn't affect
my own opinion.

[...]
> > You're trying to introduce a new structure in the language just to turn
> > these usage cases into slightly more readable code (in your opinion)
> > but at the same time you don't want to use the features already in the
> > language which would turn your own example into more readable code and
> > would kill the need for the new presented structures.
> 
> The minimum and maximum objects are not structures.  They are singleton
> instances with specific behavior when compared against other objects. 
> No more, no less.

Heh.. pointless.

> Hiding the special cases inside a class, doesn't remove the special
> cases, it just moves them somewhere else.  I could have certainly just
> given the class, which would have contained __cmp__ functions that
> looked something like this:
> 
> class DijkstraSPElement_Max:
>     #initialization
>     def __cmp__(self, other):
>         return cmp(self.distance, other.distance)
> 
> class DijkstraSPElement_None:
>     #initialization
>     def __cmp__(self, other):
>         if self.distance is None:
>             if other.distance is None:
>                 return 0
>             return 1
>         elif other.distance is None:
>             return -1
>         return cmp(self.distance, other.distance)
> 
> Hey, it makes a good case for the PEP; maybe I'll stick it in there if I
> have time this afternoon.  Thank you for the sugestion.

Ouch! It's getting worse. :-)

Put *that* example in your PEP, please:

class Node:
    def __init__(self, node, parent=None, distance=None, visited=False):
        self.node = node
        self.parent = parent
        self.distance = distance
        self.visited = visited

    def __cmp__(self, other):
        pair = self.distance, other.distance
	if None in pair:
	    return cmp(*pair)*-1
	return cmp(*pair)
        
def DijkstraSP_table(graph, S, T):
    table = {}
    for node in graph.iterkeys():
        table[node] = Node(node)
    table[S] = Node(S, distance=0)
    cur = min(table.values())
    while (not cur.visited) and cur.distance != None:
        node.visited = True
        for cdist, child in graph[node]:
            ndist = node.distance+cdist
            childnode = table[child]
            if not childnode.visited and \
               (childnode.distance is None or ndist < childnode.distance):
                childnode.distance = ndist
        cur = min(table.values())
    if not table[T].visited:
        return None
    cur = T
    path = [T]
    while table[cur].parent is not None:
        path.append(table[cur].parent)
        cur = path[-1]
    path.reverse()
    return path

[...]
> > Using examples which are better written in a more clear way inside a PEP
> > which is purposing a structure for better readability of code is not a
> > good way to convince people.
> 
> Are you saying that I should place comments describing what the
> algorithm is doing inside the examples?  Perhaps.

No, I meant you should do something towards what I've presented above.

-- 
Gustavo Niemeyer
http://niemeyer.net



More information about the Python-Dev mailing list