Alternative iterator syntax
Rainer Deyke
root at rainerdeyke.com
Wed Feb 21 15:29:21 EST 2001
"Huaiyu Zhu" <hzhu at users.sourceforge.net> wrote in message
news:mailman.982769240.31345.python-list at python.org...
> Following suggestion by Jeff Petkau <jpet at eskimo.com>,
> (http://mail.python.org/pipermail/python-list/2001-February/029944.html),
> here is a different proposal for iterators.
>
> Like the colon-syntax proposal, it achieves the following
>
> 1. It provides an extensible iterator interface without pretending to
> provide random access to elements.
> 2. It resolves the endless "i indexing sequence" debate.
> 3. It allows performance enhancements to dictionary iteration.
> 4. It is completely backward compatible.
5. It will allow iteration over "sequences" longer than 'sys.maxint'.
> They MAY but NEED NOT define a __len__ method, which may or may not
> return semantically correct result.
What is the point in allowing a semantically incorrect '__len__'?
> If A defines __next__, the above is interpreted as the equivalence of
> (__got is an invisible variable):
<snip>
> Else if A defines __list__, then "for x in A:" is interpreted as "for
> x in A.__list__():". Note that every list is an iterator (see below).
(see below)
> Else if A is a callable object, then "for x in A:" is interpreted as
> "for x in A():".
Won't this interfere with existing user-defined sequences that are also
callable but don't support the iterator protocol?
> 2. The in operator:
>
> Consider the expression
> (a, b, c, ...) in A:
>
> If A defines __contains__, the above is interpreted as the equivalence
> of:
> A.__contains__((a,b,c, ...))
>
> Else if A defines __list__, then "x in A" is interpreted as "x in
> A.__list__()". Note that every list is an iterator (see below).
Why is '__next__' not used?
> Applications to Builtins and Other Common Situations:
>
> 1. Sequences. The builtin sequence types (list, tuple, string) are
> changed to iterators by adding the three magic methods __next__,
> __contains__ and __list__. The following is always true:
>
> x.__list__() == list(x)
This is really really bad. Iterators have state. Tuples and strings do
not. Consider the following:
a = 'Hell, O world!'
a.__next__()
b = 'Hell, O world!'
print '"%s", "%s", %d' % (a, b, a == b) # Are they the same?
print a.__next__(), b.__next__()
Don't do it. Instead, either the original iteration protocol should be left
in place as backup, or there should be some automagic way of generating
iterators form sequences.
> In addition, Each sequence object x defines two attributes (indexes,
> items) that are themselves iterators. The arity of indexes is 1, that
> of items is 2.
NOOooooOoooOo!!!!!!!!
>
> x.indexes.__list__() == range(len(x))
'range(len(x))' returns a list of integers, not a list of 1-tuples. This
may not be significant for sequences, but consider mappings:
> 2. Mappings. Each mapping object x defines three attributes (keys,
> values, items) that are callable iterators. The arity of keys and
> values is 1, that of items is 2.
The following is currently valid Python code:
d = {('cheese', 'shop') : ('dead', 'parrot') }
for a, b in d.keys():
print a, b # Prints 'cheese shop'
for a, b in d.values():
print a, b # Prints 'dead parrot'
Setting the arity of 'keys' and 'values' to 1 breaks this.
> 4. The Iterator class. An iterator class could be included with
> standard python, so that one could write:
>
> a = Iterator([1,2,3]) # Or a = Iterator(); a.__list__ = [1,2,3]
I thought the '__list__' attribute of iterators was a method that returns a
list, not a list.
> 1. Following Python tradition, using magic methods is preferred to
> adding special syntaxes. Special syntaxes are only added if existing
> syntax space is not large enough to call these magic methods, which
> is not the case here.
I thought all magic methods were merely ways of implementing the
functionality of built-in types in classes, i.e. e.g. '__add__' is never
called directly, but merely used by the built-in types 'class instance' to
implement the syntax 'a + b'.
> 2. Iterators should not be limited to what they can emit, so the items
> should be allowed to be tuples of any desired arity. For example, an
> iterator over spatial points may be used as "x,y,z in points". This
> generality is not possible with the colon based special syntax that
> is only applicable to lists and dicts.
Why must iterators emit tuples at all?
> Appendix: Application of the __arity__ syntax to general tuple unpacking.
>
> This is independent of the iterator issue, but it is closely related to
> the outputs of iterators. The __arity__ syntax proposed above appears
> to also solve tuple unpacking problems elsewhere.
<snip>
I am totally against the '__arity__' syntax. It only seems to replace one
thrown exception for another. Besides, in my experience, code like the
following is not uncommon:
def return_tuple(n):
return (0,) * n
a, b = return_tuple(2)
x, y, z = return_tuple(3)
Such code could not use '__arity__', reducing it to special case syntax
sugar.
--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor
More information about the Python-list
mailing list