General question about Python design goals

Bengt Richter bokr at oz.net
Mon Nov 28 23:13:22 EST 2005


On 27 Nov 2005 21:01:49 -0800, aahz at pythoncraft.com (Aahz) wrote:

>In article <dmdsf0$eus$1 at online.de>,
>Christoph Zwerschke  <cito at online.de> wrote:
>>Aahz wrote:
>>> Christoph deleted his own attribution:
>>>>
>>>>For instance, I just wanted to use the index() method on a tuple which 
>>>>does not work. ...
>>>
>>> Because Guido believes that tuples should be primarily used as
>>> lightweight replacements for C structs.  Therefore they have minimal
>>> functionality.
>>
As has been pointed out list(atuple).alistmethod(thelistmethodsargs) works
to get the benefit of list methods. In fact, list(anyiterable).alistmethod(thelistmethodsargs)
works too. Maybe list is not the best possible unifier for defining sequence-applicable methods.
I'm getting at something ;-)

Tuples are iterable. Therefore, once a tuple is e.g. turned into an iterator object,
Guido's feelings about the appropriate uses for tuples have been laundered away.
Someone is saying "I want to treat this as a sequence" when they write, e.g., iter(atuple).

If iter were a type instead of a built-in function, it could have methods that
apply to all sequences. Then you could write iter(any_iterable).count(match_element)
and know that that .count is uniformly available that way for any sequence passed
to the iter constructor.

IMO this would be better than demanding that all iterable objects themselves have
all the handy sequence-applicable methods.

ISTM many of the itertools goodies could be written as methods of iter, especially if you expanded
the iter call signature to accept multiple iterables, so e.g., iter('abc', '12').zip()
would produce an iterator like izip. Note this iterator would also be an iter or iter subclass instance,
and so would have methods available so you could chain them like iter('abc','123').zip().slice(1,2)
(I am dropping the prefixed 'i'). Also, these methods might have useful variants controlled by arguments,
e.g., iter(seq1, seq2).zip(pad='<missing>') might insert the pad keyword argument (if present) for
to pad out shorter sequences to the same length as the longest, like map(None, ...)

IOW, all the methods that apply orthogonally to sequences should perhaps be methods
available to iter instances. Currently you can only pass a single iterable or
a callable, sentinel pair to iter, but that could be expanded.

Further example...

    iter(open('afile')).filter(lambda line:line.strip().startswith('From:')

would return a suitable filtering iterator, which in turn would have further
iter methods available if desired, so

    iter(open('afile')).filter(lambda line:line.strip().startswith('From:').len()

might return the length (hopefully optimized for iterators that have the opportunity to
pass though actual length from their source, but otherwise working through the sequence).
(Of course, if open returned a standard iter subclass instance, you wouldn't have
to write iter(open(...)))

ISTM this would be a powerful way of composing pipelined iterators and unifying treatment
of sequences, as well as providing a logical place to add useful general sequence-applicable methods.

Later you could talk about syntactic sugar for spelling e.g. iter(atuple).count(thing) more concisely.
Maybe a double attribute dot (for sequence mnemonic)? E.g., obj.. <=> iter(obj) so
    atuple..count(thing)
would be sugar for
    __builtins__.iter(atuple).count(thing)
(I added __builtins__ to let you be perverse and define a local iter for use as
    iter(atuple).surprising(thing)
also if you wanted to). But sugar aside,
I think it would be nice just to have a subclassable iter type with good base methods.

But (perhaps ;-) the main point here is not my latest OTTOMH idea/BF.
The point is to illustrate that there may be unexplored avenues available to satify those
who say, "But a tuple is a sequence a lot like list, so why don't they have the same
handy sequence methods?" Which means that I suspect there is something like premature
NIH-idea-xenophobic rejection going on sometimes, where imagination might be more helpful
and a way could be found to make a concept fit satisfyingly in a place not immediately recognized.

IOW, I generally like orthogonality, so I sympathize with the desire to have .count available
easily for any sequence, including tuples. But I don't think that means that all iterable
objects should _themselves_ have all list methods etc.


Another idea would be to tag names with '!' to indicate that a name space "path" should be searched
before or after normal name search. So e.g. if there were a __nspath__ visible, e.g. like

    __nspath__ == [__builtins__.__dict__, dict(index=lambda obj, el:list(obj).index(el))]

then

    atuple.!index(42)

would mean something like (untested ;-)

    (d['index'] for d in __nspath__ if 'index' in d).next().__get__(atuple, type(atuple))(42)

this could also be written as

    atuple.index!(42)

which would mean if atuple had and index method, that would immediately satisfy the search, but
the search would continue at the '!' point if not. The default nspath could be in __builtins__
optimized unless a module gets a global __nspath__ at import time. But that's premature optimization ;-)

Hm, that means that obj.!method produces a bound method with a function
dynamically borrowed potentially from anywhere ;-) Hm2, should it be an error if there's no __get__, or
should that be a mechanism for supplycing a default attribute value through an extended
(by __nspath__) search?

Should I have started a new thread for this kind of idea musing? ;-)

>>But the problem is that the tutorials and manuals give the impression 
>>that the difference between lists and tuples is only mutablity versus 
>>immutability. They don't talk about such considerations and honestly 
>>speaking even now I know that it does seem more plausible for me.
>
>Then feel free to submit patches for the docs.
This is easy to say, and maybe the docs maintainers are accomodating,
but I'd be the average reader wouldn't have a concept of how a "patch"
should be prepared. I know the info is not far away in the python.org site
but still, is there an interface that will bring up a doc page in a browser
and let you select e.g. a paragraph and pop up a form for a before/after
rewrite proposal (maybe with integrated preview, a la slashdot submissions)?
That's wiki-like, but I'm thinking a tailored utility. Given reasonably
structured doc sources, I wouldn't think it would be too bad a project.
Not that I'm volunteering to write that particular thing ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list