Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

General question about Python design goals

6 views
Skip to first unread message

Christoph Zwerschke

unread,
Nov 27, 2005, 8:12:19 PM11/27/05
to
Sometimes I find myself stumbling over Python issues which have to do
with what I perceive as a lack of orthogonality.

For instance, I just wanted to use the index() method on a tuple which
does not work. It only works on lists and strings, for no obvious
reason. Why not on all sequence types?

Or, another example, the index() method has start and end parameters for
lists and strings. The count() method also has start and end parameters
for strings. But it has no such parameters for lists. Why?

However when I ask such things I noticed I get answers like: "Is there a
use case?" "You can do it some other way so it is not worth bothering."

Let me ask back: Do I really need to bother and justify it with a use
case in a case where the language can be easily made more consistent or
orthogonal without breaking anything?

What about design goals such as:

- orthogonality
- coherence, consistency
- principle of least astonishment ("Python fits my brain")
- simplicity ("kiss" principle)
- aesthetics, symmetry

Actually, which priority have the above design goals for Python? Are
other design goals considered more important?

If I compare them with the "Zen of Python", I find some of the above:

consistency -> Special cases aren't special enough to break the rules
simplicity -> Simple is better than complex
aesthetics -> Beautiful is better than ugly

Actually, concerning the last two, you already need to understand the
Zen of Python to decide if something is "simple" or even "beautiful", so
they are not really suitable to *define* the Zen of Python. For me, a
programming language is beautiful if it is orthogonal and coherent. But
for others, this may be different. Somehow, I'm missing a direct
allusion to the following in the Zen of Python:

- orthogonality
- principle of least astonishment

Maybe I am I lacking the satori of a real Python Zen master?

-- Christoph

Robert Kern

unread,
Nov 27, 2005, 8:30:22 PM11/27/05
to pytho...@python.org
Christoph Zwerschke wrote:
> Sometimes I find myself stumbling over Python issues which have to do
> with what I perceive as a lack of orthogonality.
>
> For instance, I just wanted to use the index() method on a tuple which
> does not work. It only works on lists and strings, for no obvious
> reason. Why not on all sequence types?
>
> Or, another example, the index() method has start and end parameters for
> lists and strings. The count() method also has start and end parameters
> for strings. But it has no such parameters for lists. Why?
>
> However when I ask such things I noticed I get answers like: "Is there a
> use case?" "You can do it some other way so it is not worth bothering."
>
> Let me ask back: Do I really need to bother and justify it with a use
> case in a case where the language can be easily made more consistent or
> orthogonal without breaking anything?

Yes. If it's not going to be used, then there's not much point.
Practicality beats purity, and all that.

However, I will note that if you were to present us with a working patch
with documentation and unittests, then you'll probably get responses
along the lines of "Thank you!", instead.

--
Robert Kern
rober...@gmail.com

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Paul Rubin

unread,
Nov 27, 2005, 9:18:39 PM11/27/05
to
Robert Kern <rober...@gmail.com> writes:
> Yes. If it's not going to be used, then there's not much point.
> Practicality beats purity, and all that.

Geez man, "practicality beats purity" only means that if maintaining
purity of something is impractical, you can judiciously let purity
slide. It doesn't mean every slapdash kludge you can throw together
is acceptable for a widely-used distro, just because it works for the
cases you happened to think of at the moment you wrote it.

Wanting to handle the .count() parameters the same way for lists and
strings does not present any practical obstacles. So purity is not in
conflict with practicality there. The lack of orthogonality for that
operation is simply a wart.

Robert Kern

unread,
Nov 27, 2005, 9:46:07 PM11/27/05
to pytho...@python.org
Paul Rubin wrote:
> Robert Kern <rober...@gmail.com> writes:
>
>>Yes. If it's not going to be used, then there's not much point.
>>Practicality beats purity, and all that.
>
> Geez man, "practicality beats purity" only means that if maintaining
> purity of something is impractical, you can judiciously let purity
> slide. It doesn't mean every slapdash kludge you can throw together
> is acceptable for a widely-used distro, just because it works for the
> cases you happened to think of at the moment you wrote it.

Fine. Allow me to rephrase. Development is primarily motivated by
practical needs and guided by notions of purity. Use cases are the
primary tool for communicating those practical needs. If you can't think
of a single use case, what's the point of implementing something? Or
rather, why should someone else implement it if you don't know how you
would use it?

Aahz

unread,
Nov 27, 2005, 9:52:01 PM11/27/05
to
In article <dmdlhj$87b$1...@online.de>,

Christoph Zwerschke <ci...@online.de> wrote:
>
>For instance, I just wanted to use the index() method on a tuple which
>does not work. It only works on lists and strings, for no obvious
>reason. Why not on all sequence types?

Because Guido believes that tuples should be primarily used as
lightweight replacements for C structs. Therefore they have minimal
functionality.

>Or, another example, the index() method has start and end parameters for
>lists and strings. The count() method also has start and end parameters
>for strings. But it has no such parameters for lists. Why?

That's a fair cop. Submit a patch and it'll probably get accepted.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"If you think it's expensive to hire a professional to do the job, wait
until you hire an amateur." --Red Adair

Christoph Zwerschke

unread,
Nov 27, 2005, 9:52:57 PM11/27/05
to
>>Let me ask back: Do I really need to bother and justify it with a use
>>case in a case where the language can be easily made more consistent or
>>orthogonal without breaking anything?

Robert Kern wrote:

> Yes. If it's not going to be used, then there's not much point.
> Practicality beats purity, and all that.

I have nothing against "practicality beats purity". But to stay with the
examples I have given, in how far is writing list(t).index(x) more
practical than t.index(x)?

And by the way, if we are speaking about practicality here, are we
speaking about practicality for the Python developers or for the Python
users? This may be sometimes be in opposition.

Let me give an extreme example: Assume the count() method for strings
would have been called "numberofsubstringsinthestring()" and I argue it
should be called "count()" because that is shorter and how it is called
for lists. What should I give as a "use case" here? Must I give "use
cases" if the issue is about convenience/simplicity/elegance?

> However, I will note that if you were to present us with a working patch
> with documentation and unittests, then you'll probably get responses
> along the lines of "Thank you!", instead.

Not everybody has the time and skills to provide that. Ordinary people
from the Python user base should be given the opportunity to make
suggestions for improvement - of course not in the tone of "I
demand...", but they should not be automatically regarded as "demanding"
if they just utter their opinion or make a suggestion either.

Even if I had the time and skills, before starting to work on a patch,
unittests etc. I still would first discuss with others whether my
suggestion is reasonable and would be appreciated by the "user base",
developers and the BDFL. Just take the example of the following patch:
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=403693&group_id=5470

It was not rejected by reason of missing unittests or documentation, but
the very idea was rejected.

Actually, I'm not keen on being a protagonist for this issue or starting
a hard-bitten discussion about this and defend the idea if everybody is
against or nobody cares. It does not bother me that much either.

But it just led me to the general question: Which significance actually
have design features such as orthogonality for Python?

-- Christoph

Christoph Zwerschke

unread,
Nov 27, 2005, 10:10:24 PM11/27/05
to
>>For instance, I just wanted to use the index() method on a tuple which
>>does not work. ...

Aahz wrote:

> Because Guido believes that tuples should be primarily used as
> lightweight replacements for C structs. Therefore they have minimal
> functionality.

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.

-- Christoph

Robert Kern

unread,
Nov 27, 2005, 10:10:15 PM11/27/05
to pytho...@python.org
Christoph Zwerschke wrote:
>>>Let me ask back: Do I really need to bother and justify it with a use
>>>case in a case where the language can be easily made more consistent or
>>>orthogonal without breaking anything?
>
> Robert Kern wrote:
>
>>Yes. If it's not going to be used, then there's not much point.
>>Practicality beats purity, and all that.
>
> I have nothing against "practicality beats purity". But to stay with the
> examples I have given, in how far is writing list(t).index(x) more
> practical than t.index(x)?

I'm not arguing that the things you mentioned shouldn't be changed. I'm
saying that use cases really are important in making design decisions.
You just provided one. Congratulations.

> And by the way, if we are speaking about practicality here, are we
> speaking about practicality for the Python developers or for the Python
> users? This may be sometimes be in opposition.

As Paul noted, it was a misuse of the phrase. I withdraw it.

>>However, I will note that if you were to present us with a working patch
>>with documentation and unittests, then you'll probably get responses
>>along the lines of "Thank you!", instead.
>
> Not everybody has the time and skills to provide that. Ordinary people
> from the Python user base should be given the opportunity to make
> suggestions for improvement - of course not in the tone of "I
> demand...", but they should not be automatically regarded as "demanding"
> if they just utter their opinion or make a suggestion either.
>
> Even if I had the time and skills, before starting to work on a patch,
> unittests etc. I still would first discuss with others whether my
> suggestion is reasonable and would be appreciated by the "user base",
> developers and the BDFL. Just take the example of the following patch:
> https://sourceforge.net/tracker/?func=detail&atid=305470&aid=403693&group_id=5470
>
> It was not rejected by reason of missing unittests or documentation, but
> the very idea was rejected.

And it also appears to have nothing to do with the lack of proffered use
cases but (primarily) Guido's thoughts about how the different objects
are supposed to be used. That's why use cases are so important. They
allow developers to talk about real, concrete issues.

bon...@gmail.com

unread,
Nov 27, 2005, 10:20:35 PM11/27/05
to
That is the problem of the tutorial or manual, don't read them as if
they are ISO specs.

Peter Hansen

unread,
Nov 27, 2005, 10:20:18 PM11/27/05
to pytho...@python.org
Christoph Zwerschke wrote:
> But it just led me to the general question: Which significance actually
> have design features such as orthogonality for Python?

Probably very little. Python has not so much been designed as evolved.
Plus it's a fairly mature language (over 14 years old), and I think in
such a case that elements of design tend to be obscured by the many
changes layered on top. (For example, I hardly recognize the C++ that I
learned in the language that struggles on today.)

While the goal of orthogonality may factor into some people's reasons
for implementing certain changes, it's not (apparently) a primary
motivation for many of the ones doing work on the Python core. If more
people with such motivations had been working on the core, it's likely
Python would have more of these sorts of "gaps" filled in.

(The corollary, of course, is that there would be other gaps, and they
would be more practical ones, so other people would probably be
suggesting things like "wouldn't it be good if Python had a Unicode type
instead of all these little-used functions that make the language nice
and orthogonal but aren't really necessary". ;-) )

-Peter

Paul Rubin

unread,
Nov 27, 2005, 10:49:26 PM11/27/05
to
Robert Kern <rober...@gmail.com> writes:
> Fine. Allow me to rephrase. Development is primarily motivated by
> practical needs and guided by notions of purity.

That's bogus; if there was a discrepancy someone noticed and had to
work around, there's already been a practical failure, just not a
severe one. Development should be guided by doing things right when
possible, making allowances for practical considerations that
sometimes call for compromise. It's generally far better to do
something right the first time than to do something broken and have to
fix it later. Those XP platitudes about prototyping and refactoring
are for when the program is still under development and the
requirements have not yet been discovered, and unfixed bogosity
affects just a few people (developers and testers). When a program
has been declared finished and shipped to millions of users, any
bogosity remaining in it has a much larger effect, so bogosity should
be minimized.

> Use cases are the primary tool for communicating those practical
> needs. If you can't think of a single use case, what's the point of
> implementing something? Or rather, why should someone else implement
> it if you don't know how you would use it?

I can't think of a single use case for the addition (+) operator
working where either of the operands happens to be the number
0x15f1ef02d9f0c2297e37d44236d8e8ddde4a34c96a8200561de00492cb94b82 (a
random number I just got out of /dev/urandom). I've never heard of
any application using that number, and the chances of it happening by
coincidence are impossibly low. But if Python were coded in a way
that made the interpreter crash on seeing that number, I'd call that
a bug needing fixing.

Jean-Paul Calderone

unread,
Nov 27, 2005, 10:58:32 PM11/27/05
to pytho...@python.org
On 27 Nov 2005 19:49:26 -0800, Paul Rubin <"http://phr.cx"@nospam.invalid> wrote:
>Robert Kern <rober...@gmail.com> writes:
>> Use cases are the primary tool for communicating those practical
>> needs. If you can't think of a single use case, what's the point of
>> implementing something? Or rather, why should someone else implement
>> it if you don't know how you would use it?
>
>I can't think of a single use case for the addition (+) operator
>working where either of the operands happens to be the number
>0x15f1ef02d9f0c2297e37d44236d8e8ddde4a34c96a8200561de00492cb94b82 (a
>random number I just got out of /dev/urandom). I've never heard of
>any application using that number, and the chances of it happening by
>coincidence are impossibly low. But if Python were coded in a way
>that made the interpreter crash on seeing that number, I'd call that
>a bug needing fixing.

If you seriously believe what you just wrote, you have failed to
understand the phrase "use case" (and possibly a lot of other
things related to programming ;)

However (fortunately for you) I suspect you don't. If you really
did, you may want to pick up one of those platitude-filled XP books
and give it a careful read. You may find there's more there than
you were previously aware.

Jean-Paul

Aahz

unread,
Nov 28, 2005, 12:01:49 AM11/28/05
to
In article <dmdsf0$eus$1...@online.de>,
Christoph Zwerschke <ci...@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.
>
>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.

PS: If you want further responses from me, please follow standard Usenet
quoting conventions (like those above).

Paul Rubin

unread,
Nov 28, 2005, 12:43:44 AM11/28/05
to
Jean-Paul Calderone <exa...@divmod.com> writes:
> >I can't think of a single use case for the addition (+) operator
> >working where either of the operands happens to be the number
> >0x15f1ef02d9f0c2297e37d44236d8e8ddde4a34c96a8200561de00492cb94b82 (a
> >random number I just got out of /dev/urandom).
>
> If you seriously believe what you just wrote, you have failed to
> understand the phrase "use case" (and possibly a lot of other
> things related to programming ;)

Heh, you must not remember the famous Pentium FDIV bug, where the
Pentium gave incorrect results for floating point division with
certain rare combinations of operands. Intel at first refused to
acknowledge that the bug was a real problem (although it had already
been found and quietly fixed in later steppings), then refused to
replace people CPU's unless they could explain their use case where
the error could cause them a practical problem. My school's biology
lab got its Pentiums exchanged by claiming it was using them to model
some kind of experimental drug treatment (I don't know whether the
claim was true) but other people just got told: sorry, but what you're
doing doesn't need correct FDIV results. Intel of course eventually
had to back down and exchange everyone's cpu's after a huge public
outcry.

> However (fortunately for you) I suspect you don't. If you really
> did, you may want to pick up one of those platitude-filled XP books
> and give it a careful read. You may find there's more there than
> you were previously aware.

I've read some of the XP stuff. I see it mostly as a way of
explaining normal programmers' instincts to PHB's. If the books did
some good in reducing PHB interference in some projects, that's nice;
however, while I felt that the general approach to programming running
through them was good, the specific practices and the type of
following they got bordered on cultish.

Antoon Pardon

unread,
Nov 28, 2005, 4:03:23 AM11/28/05
to
Op 2005-11-28, Aahz schreef <aa...@pythoncraft.com>:

> In article <dmdlhj$87b$1...@online.de>,
> Christoph Zwerschke <ci...@online.de> wrote:
>>
>>For instance, I just wanted to use the index() method on a tuple which
>>does not work. It only works on lists and strings, for no obvious
>>reason. Why not on all sequence types?
>
> Because Guido believes that tuples should be primarily used as
> lightweight replacements for C structs. Therefore they have minimal
> functionality.

I find that a bit contradictory with the fact that if you want list like
structures as a dictionary key, you are mostly advised to cast them
as tuples.

So suppose I want a dictionary, where the keys are colours, represented
as RGB triplets of integers from 0 to 255. A number of things can be
checked by index-like methods.

e.g.

def iswhite(col):
return col.count(255) == 3

def primary(col):
return col.count(255) == 1 and col.count(0) == 2

def secondary(col):
return col.count(255) == 2 and col.count(0) == 1


So, what should I use to implement this? Whether I choose
lists or tuples, I will end up either copying a lot from
lists to tuples or vice versa, to get the functionality
I need, or I will have to implement functionality myself
that basically is already in the language.

I also find the use of C-structs and tuples completly different.
If I need a C-struct like object, I go for Bunch, Rec or something
similar. Something that uses field identifiers to address components,
Not something that uses indexing.

--
Antoon Pardon

Fredrik Lundh

unread,
Nov 28, 2005, 4:23:17 AM11/28/05
to pytho...@python.org
Christoph Zwerschke wrote:

> What about design goals such as:
>
> - orthogonality
> - coherence, consistency
> - principle of least astonishment ("Python fits my brain")
> - simplicity ("kiss" principle)
> - aesthetics, symmetry
>
> Actually, which priority have the above design goals for Python? Are
> other design goals considered more important?

- A Foolish Consistency is the Hobgoblin of Little Minds
- Hypergeneralization Sucks

</F>

Antoon Pardon

unread,
Nov 28, 2005, 5:27:51 AM11/28/05
to
Op 2005-11-28, Fredrik Lundh schreef <fre...@pythonware.com>:

What is so foolish about the consistency that all sequence types
have a count method?

The way this "pearl of wisdom" is used in this newsgroup, I expect
one day someone to use "+" for substraction and '-" for addition and
then when people complain about that not being consistent they get
answered by the above quote.

--
Antoon Pardon

Sebastien Douche

unread,
Nov 28, 2005, 6:34:53 AM11/28/05
to pytho...@python.org
On 11/28/05, Christoph Zwerschke <ci...@online.de> wrote:
> Sometimes I find myself stumbling over Python issues which have to do
> with what I perceive as a lack of orthogonality.

I use this thread to asking on python conception : why python have so
many builtins ?
I cannot understand why we use a builtins for open a file. Is it a old
decision ? If anyone have a pointer of this or can explain me.

Regards.


--
Sébastien Douche <sdo...@gmail.com>

Duncan Booth

unread,
Nov 28, 2005, 7:57:33 AM11/28/05
to
Antoon Pardon wrote:

> So suppose I want a dictionary, where the keys are colours, represented
> as RGB triplets of integers from 0 to 255. A number of things can be
> checked by index-like methods.
>
> e.g.
>
> def iswhite(col):
> return col.count(255) == 3
>
> def primary(col):
> return col.count(255) == 1 and col.count(0) == 2
>
> def secondary(col):
> return col.count(255) == 2 and col.count(0) == 1

Just because you *can* implement these by treating your colour like a list
doesn't make it a good idea. Treating them as opaque values makes these
particular tests clearer:

def iswhite(col):
return col==WHITE

def primary(col):
return col in (RED,GREEN,BLUE)

def secondary(col):
return col in (CYAN,MAGENTA,YELLOW)

If you relax your definition of primary to simply require that two planes
are black then you may have a case where you want to treat the colour
planes as a list, but if you convert it explicitly then you'll be better
placed to keep the code working when someone decides to add an alpha
channel or to switch the representation to CMYK.

def anyshadeprimary(col):
return [col.red, col.green, col.blue].count(0)==2
# or
return col.toRGB().count(0)==2

So it looks to me as though you want col to be a type (which might be a
subclass of tuple) but a list would be a mistake.

Antoon Pardon

unread,
Nov 28, 2005, 8:17:11 AM11/28/05
to
Op 2005-11-28, Duncan Booth schreef <duncan...@invalid.invalid>:

> Antoon Pardon wrote:
>
>> So suppose I want a dictionary, where the keys are colours, represented
>> as RGB triplets of integers from 0 to 255. A number of things can be
>> checked by index-like methods.
>>
>> e.g.
>>
>> def iswhite(col):
>> return col.count(255) == 3
>>
>> def primary(col):
>> return col.count(255) == 1 and col.count(0) == 2
>>
>> def secondary(col):
>> return col.count(255) == 2 and col.count(0) == 1
>
> Just because you *can* implement these by treating your colour like a list
> doesn't make it a good idea. Treating them as opaque values makes these
> particular tests clearer:

You are getting sidetracked. Whether this is the best possible
implementation here is not the issue. This example is just
to illustrate.

I'm sure I could come up with an other example where I would like
to have both some list method and use it as a dictionary key and
again people could start about that implementation having some
flaws and give better implementations.

I'm just illustrating that some list-like methods with tuples
could be usefull.

--
Antoon Pardon

Duncan Booth

unread,
Nov 28, 2005, 9:18:18 AM11/28/05
to
Antoon Pardon wrote:

> I'm sure I could come up with an other example where I would like
> to have both some list method and use it as a dictionary key and
> again people could start about that implementation having some
> flaws and give better implementations.
>
> I'm just illustrating that some list-like methods with tuples
> could be usefull.
>

But you aren't illustrating that at all. You came up with an example which
showed, at least to me, a good argument why tuples should *not* have list
methods.

If you can come up with a better example that would be good; if any other
example is as flawed then perhaps it shows that your basic assumption is
wrong.

Antoon Pardon

unread,
Nov 28, 2005, 9:39:25 AM11/28/05
to
Op 2005-11-28, Duncan Booth schreef <duncan...@invalid.invalid>:
> Antoon Pardon wrote:
>
>> I'm sure I could come up with an other example where I would like
>> to have both some list method and use it as a dictionary key and
>> again people could start about that implementation having some
>> flaws and give better implementations.
>>
>> I'm just illustrating that some list-like methods with tuples
>> could be usefull.
>>
> But you aren't illustrating that at all. You came up with an example which
> showed, at least to me, a good argument why tuples should *not* have list
> methods.

No I gave an example, you would implement differently. But even
if you think my example is bad, that would make it a bad argument
for tuples having list methods. That is not the same as being
a good argument against tuples having list methods. The trouble is
to really convince would probably require a complete worked out module,
but then I don't have the time to come up with a complete worked out
module just to illustrate something. So I come up with just a skeleton
of something to get the idea across and what happens is that the
attention goes to how the skeleton could be approved in other ways,
instead of trying to understand what ideas are trying to be
communicated.

--
Antoon Pardon

Fredrik Lundh

unread,
Nov 28, 2005, 9:55:32 AM11/28/05
to pytho...@python.org
Duncan Booth wrote:

> > I'm just illustrating that some list-like methods with tuples
> > could be usefull.
> >
> But you aren't illustrating that at all.

"But assume that I have some other use case"

</F>

Duncan Booth

unread,
Nov 28, 2005, 10:29:02 AM11/28/05
to
Antoon Pardon wrote:

>
> No I gave an example, you would implement differently. But even
> if you think my example is bad, that would make it a bad argument
> for tuples having list methods. That is not the same as being
> a good argument against tuples having list methods.

Tuples don't have list methods, therefore any code which seems to require a
tuple with list methods should make you stop and consider whether your
design is wrong. Your example made me consider your design was wrong. If
tuples did have list methods you would have gone ahead with a poor design.

That is why I said that, to me, it is an argument against giving tuples the
additional methods. It is a fairly weak argument though, so if you do have
some other use case you could easily prove me wrong.

Paul Boddie

unread,
Nov 28, 2005, 10:43:37 AM11/28/05
to
Antoon Pardon wrote:

> Duncan Booth wrote:
> > But you aren't illustrating that at all. You came up with an example which
> > showed, at least to me, a good argument why tuples should *not* have list
> > methods.

For what it's worth, I don't agree with that analysis, but anyway...

> No I gave an example, you would implement differently. But even
> if you think my example is bad, that would make it a bad argument
> for tuples having list methods. That is not the same as being
> a good argument against tuples having list methods.

In this case, I rather agree with the pragmatic responses earlier in
the thread: that it was probably an oversight that tuples lack the
count, index and (arguably) sorted methods, and that patches would
probably be welcome to rectify this state of affairs. Personally, I
find certain sequence-like characteristics of strings more irritating
on occasions, and if one had to convert strings to lists in order to
iterate over the characters (as one has to do in various other
high-level languages), I probably wouldn't find that so inconvenient.
But then, such a change would probably disrupt the existence of other
useful aspects of strings: index-based access to characters, slicing,
and so on. I'm therefore not inclined to shout about such matters in
such a way that I then have to defend my subjective line of thinking
whilst proposing an objectively acceptable alternative.

I actually think it's good to question certain aspects of the language
in the way being done in this thread, despite unconvincing attempts to
defend the status quo (and the ever present threat of a giant hedgehog
emerging from behind a building with large signs reading "Pythonic" and
"Zen of Python" stuck on its spines), but I personally wouldn't spend
too much time on such matters myself.

Paul

Aahz

unread,
Nov 28, 2005, 11:10:31 AM11/28/05
to
In article <1133192617.0...@o13g2000cwo.googlegroups.com>,

Paul Boddie <pa...@boddie.org.uk> wrote:
>
>In this case, I rather agree with the pragmatic responses earlier in
>the thread: that it was probably an oversight that tuples lack the
>count, index and (arguably) sorted methods, and that patches would
>probably be welcome to rectify this state of affairs.

You're wrong. I don't have time/energy to look up the relevant posts,
but Guido has been extremely clear in the past that tuples are *NOT*
going to grow methods.

Paul Boddie

unread,
Nov 28, 2005, 11:17:35 AM11/28/05
to
Aahz wrote:
> You're wrong. I don't have time/energy to look up the relevant posts,
> but Guido has been extremely clear in the past that tuples are *NOT*
> going to grow methods.

Ah, I misread some of those other posts. Still, at least that is
consistent with saying that it wasn't worth spending much time on such
matters. ;-)

Paul

Fredrik Lundh

unread,
Nov 28, 2005, 11:10:10 AM11/28/05
to pytho...@python.org
Christoph Zwerschke wrote:

> But the problem is that the tutorials and manuals give the impression
> that the difference between lists and tuples is only mutablity versus
> immutability.

both the tutorial and the FAQ discusses the difference in terms of use
cases and recommended usage.

> Maybe I am I lacking the satori of a real Python Zen master?

I suggest you look up the phrase "bike shed effect". next, go read some
recent PEP:s to see what's really going on in the Python design universe.

</F>

Aahz

unread,
Nov 28, 2005, 1:11:43 PM11/28/05
to
In article <mailman.1274.1133177...@python.org>,

Sebastien Douche <sdo...@gmail.com> wrote:
>
>I use this thread to asking on python conception : why python have so
>many builtins ?
>I cannot understand why we use a builtins for open a file. Is it a old
>decision ? If anyone have a pointer of this or can explain me.

One of the primary goals for Python is to make it easy to use for new
programmers. Particularly for sysadmins, opening a file for reading and
writing is considered such a basic task that it's part of the builtins.

There are some builtins slated for removal in Python 3.0 (e.g. apply(),
which is superseded by *args/**kwargs being allows on the calling side).

Christoph Zwerschke

unread,
Nov 28, 2005, 5:08:49 PM11/28/05
to
Fredrik Lundh schrieb:

> Christoph Zwerschke wrote:
>>But the problem is that the tutorials and manuals give the impression
>>that the difference between lists and tuples is only mutablity versus
>>immutability.
>
> both the tutorial and the FAQ discusses the difference in terms of use
> cases and recommended usage.

The tutorial does not speak about differences other than mutability. But
you're right, the C structs analogy is mentioned in the FAQ.

>>Maybe I am I lacking the satori of a real Python Zen master?
>
> I suggest you look up the phrase "bike shed effect". next, go read some
> recent PEP:s to see what's really going on in the Python design universe.

The bike shed effect is a good explanation and so true. About 8 years
ago when I started to work at my current working place at the university
I suggested that a bike shed should be provided for people like me.
Since then, a lot of million euro projects have been carried out, like
introducing SAP software and new projects are in progress. But my bike
still is getting wet and anyway, it's still bothering me.

-- Christoph


Christoph Zwerschke

unread,
Nov 28, 2005, 5:30:31 PM11/28/05
to
Aahz wrote:
>Christoph wrote:
>>Aahz wrote:

>>>Christoph wrote:
>>>>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.
>>
>>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.

Why should I patch the docs to add things that don't seem plausible for
me? I'd rather change the behavior to be more consistent instead
tweaking the docs to somehow justify the inconsistent behavior.

> PS: If you want further responses from me, please follow standard Usenet
> quoting conventions (like those above).

I am tempted to answer, "A Foolish Consistency is the Hobgoblin of
Little Minds" ;-)

No honestly, it was not in bad faith. I'm just not a regular usenet user
and believed one attribution line per post should suffice. But reading
the conventions I agree that they make sense.

And I think it's a good analogy. Some people dislike Python's stringent
whitespace syntax and "one obvious way" rule because it does not give
them freedom to write programs in their individual style. But I don't
think it's "foolish consistency" - it simply makes programs of others
more easy to read, you can concentrate on the content and not the style.
It's the same reason why people use quoting conventions. And BTW, I
think that makes particularly suited for open source and XP projects.

-- Christoph

Christoph Zwerschke

unread,
Nov 28, 2005, 5:54:54 PM11/28/05
to
Fredrik Lundh schrieb:

Ok, these are nice aphorisms with some truth. But I had to think of the
German excuse "Wer Ordnung hält ist nur zu Faul zum Suchen - ein Genie
überblickt das Chaos." ("Those who try to keep things tidy are just too
lazy to search for searching - a genius surveys the chaos").

They remind you that consistency - as every good goal - can be
overemphasized and exaggerated on the cost of other good goals, but
otherwise they have little wisdom in the realm of programming.

In the original context (http://www.emersoncentral.com/selfreliance.htm)
and IIUC, the meaning of the "foolish consistency" aphorism is:

"A great mind will not stupidly think/work consistently from one day to
the next, but is able to throw away beloved ideas, beliefs, habits,
styles etc. if he/she finds something that is better, more true or more
appropriate under changed circumstances."

Try to transfer this to programming languages: "A great programming
language does not have to function consistently from one version to the
next, you can completely throw away a well-established syntax if you
find something better." I think this would not really be desirable.

Another problem I have with that aphorisms applied to Python is that it
has some undertone of "Python is only intended to be used by great
minds" and making it usable and understandable for "little minds" is no
design goal at all. That would be a very arrogant and elitarian view.
Little minds like me should be able to say "Python fits my brain" just
as great minds. Even kids can understand Python (there's a Germany book
"Python for Kids", http://www.way2python.de/pythonbuch/kids.html) and I
think i's not disqualifying Python as a "toy language", but I consider
it rather a strength of Python. Ok, there is even a book "C++ for kids",
but I think in reality it is intended for adult beginners...

Most of all, such solgans do not explain *when* consistency is to be
considered foolish and when it is wise. Are those who suggest changes in
order to make Python more consistent with itself foolish or are those
foolish who reject this, saying that "Python has always been like that,
nobody has cared in the past and we want to stay compatible". This could
be also considered a "foolish consistency".

A programming language is not a "work of art". If you are an artist, you
may break symmetry and introduce all kinds of unexpected effects.
Actually, as an artist, you purposfully want to provoke astonishment.
But if I am using a programming language or a user interface, I don't
want to be confronted with inconsistent behavior. Here, the "principle
of least astonishment" is much more helpful (in my little mind's humble
optionion).

-- Christoph

Aahz

unread,
Nov 28, 2005, 6:03:10 PM11/28/05
to
In article <dmg0e6$j2l$1...@online.de>,

Christoph Zwerschke <ci...@online.de> wrote:
>Aahz wrote:
>>Christoph wrote:
>>>Aahz wrote:
>>>>Christoph wrote:
>>>>>
>>>>>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.
>>>
>>>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.
>
>Why should I patch the docs to add things that don't seem plausible for
>me? I'd rather change the behavior to be more consistent instead
>tweaking the docs to somehow justify the inconsistent behavior.

The problem is that Guido really is the BDFL. Unless you change his mind
(and he has been historically firm about the place of tuples), your
option for improving things is to improve the docs, if you care.

>> PS: If you want further responses from me, please follow standard Usenet
>> quoting conventions (like those above).
>
>I am tempted to answer, "A Foolish Consistency is the Hobgoblin of
>Little Minds" ;-)
>
>No honestly, it was not in bad faith. I'm just not a regular usenet user
>and believed one attribution line per post should suffice. But reading
>the conventions I agree that they make sense.

Thanks!

Peter Hansen

unread,
Nov 28, 2005, 6:33:58 PM11/28/05
to pytho...@python.org
Christoph Zwerschke wrote:
> Ok, these are nice aphorisms with some truth. But I had to think of the
> German excuse "Wer Ordnung hält ist nur zu Faul zum Suchen - ein Genie
> überblickt das Chaos." ("Those who try to keep things tidy are just too
> lazy to search for searching - a genius surveys the chaos").

Is that really the translation? "too lazy to search for searching"?
What does that mean?

Google translate doesn't help... here's it's rather comical attempt:

"Who order holds is only to putrid for looking for - a genius grasps the
chaos"

-Peter

Christoph Zwerschke

unread,
Nov 28, 2005, 6:51:36 PM11/28/05
to
Peter Hansen schrieb:

> Christoph Zwerschke wrote:
>
>> Ok, these are nice aphorisms with some truth. But I had to think of
>> the German excuse "Wer Ordnung hält ist nur zu Faul zum Suchen - ein
>> Genie überblickt das Chaos." ("Those who try to keep things tidy are
>> just too lazy to search for searching - a genius surveys the chaos").
>
>
> Is that really the translation? "too lazy to search for searching"?
> What does that mean?

Sorry. Cancel either "to search" or "for searching". I noticed I made a
lot of typos in that posting. In the German sentence, there should be
comma after "ist", and "faul" should be written with a lowercase "f".
Probably this caused additional confusion for Google...

-- Christoph

Paul Rubin

unread,
Nov 28, 2005, 6:53:17 PM11/28/05
to
Peter Hansen <pe...@engcorp.com> writes:
> Christoph Zwerschke wrote:
> > Ok, these are nice aphorisms with some truth. But I had to think of
> > the German excuse "Wer Ordnung hält ist nur zu Faul zum Suchen - ein
> > Genie überblickt das Chaos." ("Those who try to keep things tidy are
> > just too lazy to search for searching - a genius surveys the chaos").
>
> Is that really the translation? "too lazy to search for searching"?
> What does that mean?

It should just say "too lazy to search" or maybe "too lazy to be a
searcher".

Christoph Zwerschke

unread,
Nov 28, 2005, 6:55:52 PM11/28/05
to
Christoph Zwerschke wrote:
> there should be comma after "ist",

Sorry, *before* "ist". I should probably stop posting for today...

-- Christoph

Mike Meyer

unread,
Nov 28, 2005, 8:20:50 PM11/28/05
to
Christoph Zwerschke <ci...@online.de> writes:
> A programming language is not a "work of art". If you are an artist,
> you may break symmetry and introduce all kinds of unexpected
> effects. Actually, as an artist, you purposfully want to provoke
> astonishment. But if I am using a programming language or a user
> interface, I don't want to be confronted with inconsistent
> behavior. Here, the "principle of least astonishment" is much more
> helpful (in my little mind's humble optionion).

But a programming language (or UI) is not just a collection of syntax
and and interfaces - it's an implementation. You need to keep in mind
that "practicality beats purity". If following POLA makes the
implementation an order of magnitude slower or larger, then you don't
follow POLA - at least until you can do it without that cost.

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Bengt Richter

unread,
Nov 28, 2005, 11:13:22 PM11/28/05
to
On 27 Nov 2005 21:01:49 -0800, aa...@pythoncraft.com (Aahz) wrote:

>In article <dmdsf0$eus$1...@online.de>,


>Christoph Zwerschke <ci...@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

Mike Meyer

unread,
Nov 29, 2005, 12:52:25 AM11/29/05
to
bo...@oz.net (Bengt Richter) writes:
>>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.

From what's been said here before, the doc committers aren't picky
about getting patches. That requires learning whatever doc format they
use, and they understand that that's a pretty hefty burden for a one
or two-paragraph tweak on the documentation. So submitting docs in
English works. Submitting patches works *better*, but not doing so
doesn't consign your suggestions to oblivion.

Antoon Pardon

unread,
Nov 29, 2005, 3:27:43 AM11/29/05
to
On 2005-11-28, Duncan Booth <duncan...@invalid.invalid> wrote:
> Antoon Pardon wrote:
>
>>
>> No I gave an example, you would implement differently. But even
>> if you think my example is bad, that would make it a bad argument
>> for tuples having list methods. That is not the same as being
>> a good argument against tuples having list methods.
>
> Tuples don't have list methods, therefore any code which seems to require a
> tuple with list methods should make you stop and consider whether your
> design is wrong.

IMO that is a non-sequitur, because that makes what is good or bad
design dependand on the language used.

If I have a design that seems to require tuples with a count method,
then wether that is a good or bad design doesn't depend on
whether or not python allows that or not.

--
Antoon Pardon

Christoph Zwerschke

unread,
Nov 29, 2005, 4:55:11 AM11/29/05
to
Mike Meyer wrote:

> Christoph Zwerschke wrote:
>>A programming language is not a "work of art". If you are an artist,
>>you may break symmetry and introduce all kinds of unexpected
>>effects. Actually, as an artist, you purposfully want to provoke
>>astonishment. But if I am using a programming language or a user
>>interface, I don't want to be confronted with inconsistent
>>behavior. Here, the "principle of least astonishment" is much more
>>helpful (in my little mind's humble optionion).
>
> But a programming language (or UI) is not just a collection of syntax
> and and interfaces - it's an implementation. You need to keep in mind
> that "practicality beats purity". If following POLA makes the
> implementation an order of magnitude slower or larger, then you don't
> follow POLA - at least until you can do it without that cost.

I do not deny this. As an example, if tuples can be used as keys of
dicts, you might first naively assume that lists could also work. This
is not the case for practicality (performance) reasons and because it
would be difficult or impossible to guarantee the uniqueness of keys. In
this case, POLA is overruled by other goals or inherent necessities.

But that does not mean that POLA in itself is not an important guiding
principle for programming languages (or UI).

-- Christoph

Steve Holden

unread,
Nov 29, 2005, 3:33:00 AM11/29/05
to pytho...@python.org
Christoph Zwerschke wrote:
> Fredrik Lundh schrieb:
[...]

>>I suggest you look up the phrase "bike shed effect". next, go read some
>>recent PEP:s to see what's really going on in the Python design universe.
>
>
> The bike shed effect is a good explanation and so true. About 8 years
> ago when I started to work at my current working place at the university
> I suggested that a bike shed should be provided for people like me.
> Since then, a lot of million euro projects have been carried out, like
> introducing SAP software and new projects are in progress. But my bike
> still is getting wet and anyway, it's still bothering me.
>
Yes, but that's the academic world, and bike sheds are a real-world
requirement so they will tend to be ignored indefinitely.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Bengt Richter

unread,
Nov 29, 2005, 9:54:44 AM11/29/05
to
On Tue, 29 Nov 2005 00:52:25 -0500, Mike Meyer <m...@mired.org> wrote:

>bo...@oz.net (Bengt Richter) writes:
>>>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.
>
>From what's been said here before, the doc committers aren't picky
>about getting patches. That requires learning whatever doc format they
>use, and they understand that that's a pretty hefty burden for a one
>or two-paragraph tweak on the documentation. So submitting docs in
>English works. Submitting patches works *better*, but not doing so
>doesn't consign your suggestions to oblivion.
>

Ok, sounds reasonable.
BTW, no opinion on iter as a type harboring sequence-applicable methods? ;-)

Regards,
Bengt Richter

Sibylle Koczian

unread,
Nov 29, 2005, 11:03:05 AM11/29/05
to
Peter Hansen schrieb:

Automated translation in a nutshell.

--
Dr. Sibylle Koczian
Universitaetsbibliothek, Abt. Naturwiss.
D-86135 Augsburg
e-mail : Sibylle...@Bibliothek.Uni-Augsburg.DE

Fredrik Lundh

unread,
Nov 29, 2005, 10:28:13 AM11/29/05
to pytho...@python.org
Steve Holden wrote:

> > The bike shed effect is a good explanation and so true. About 8 years
> > ago when I started to work at my current working place at the university
> > I suggested that a bike shed should be provided for people like me.
> > Since then, a lot of million euro projects have been carried out, like
> > introducing SAP software and new projects are in progress. But my bike
> > still is getting wet and anyway, it's still bothering me.
> >

> Yes, but that's the academic world, and bike sheds are a real-world
> requirement so they will tend to be ignored indefinitely.

on the other hand, it's also possible that there are perfectly usable ways
to keep bikes and bike seats dry where Christoph works, but that he prefers
not to use them because they're violating some design rule.

(this is related to the drain pipe effect, where engineers spend endless
hours talking about how to make it easier to climb the drain pipe, while
everyone uses the stairs...)

</F>

Bengt Richter

unread,
Nov 29, 2005, 11:52:41 AM11/29/05
to

No, but if your requirement is to count __eq__ - matching items in a
tuple, maybe your sense of orthogonality ought to abstract out the
sequence aspect in some other way than seeing it as a seeming method
requirement for tuple. A tuple.count method has implications about
attribute access to a special object, tuple, which then you have
to deal with for every new object you introduce, unless you want to
inherit it from object, but that means object becomes a
mega swiss army knife in short order.

So IMO the thing is not to ask for a specific solution like "why
not a count method for tuples?" You'll just get answers to that literal
question, with some elaborations. Instead, if you put it in the form
of what your general requirement really is (I'm guessing ;-) which I
assume is to be able to apply list count method _functionality_ to
anything which quacks like a list, including tuples etc. In short,
anything iterable.

Now the problem is to bring program and data together with some
spelling in python. data.method() is certainly one spelling, but
so is method(data). You gain something either way. The first allows
you to associate the method and data without executing the method, i.e.,
data.method is a bound method object that has the data-method association
built in, and it can be passed around. method(data) does the call right
away and uses a diferent name space search path to find method, and is
not necessarily associated with type(data). To ask for common methods
for all objects that exhibit some similar aspect is to entangle their
types in some way or to duplicate stuff. Sometimes it's fine to
derive from a common base etc., but

why not a built-in count function that does something like (untested)

def count(obj, match_item, eq=operator.eq):
return sum(1 for item in iter(obj) if eq(item, match_item))

which would give a little flexibility about eq comparison as well as
wide applicability to any sequence? index too (untested)

def index(obj, match_item, eq=operator.eq):
try: return (i for i, item in enumerate(obj) if eq(item, match_item)).next()
except StopIteration: raise ValueError('index(seq, item): item not in seq')

why doesn't list have a find like str? ;-)

def find(obj, match_item, eq=operator.eq):
try: return (i for i, item in enumerate(obj) if eq(item, match_item)).next()
except StopIteration: return -1

One could create an alternate spelling for obj.count(thing) using the count function above.
You can spell it now as

count.__get__(obj, type(obj))(thing)

if you want to duplicate the effect of having the count function retrieved from type(obj)
as if it were a method defined there. Or you can spell it

count(obj)

which doesn't seem too bad ;-)
But now the problem is cluttering the __builtins__ space. So maybe it would be
better to write
from sequence_goodies import count
...
count(obj)

Do you really want a count method for tuple? Or is that maybe not as clean is
it seemed? All the issues aren't usually immediatly apparent, so IMO the more
we focus on abstract functionality desired, the more likely we will get
helpful solution ideas for a menu of choices, and avoid prematurely discussing
whether we should have pumpkin pie with or without whipped cream, when finally
we might all like strawberries and cream better, if someone had thought of it.

Regards,
Bengt Richter

Christoph Zwerschke

unread,
Nov 29, 2005, 5:18:34 PM11/29/05
to
Fredrik Lundh wrote:
> on the other hand, it's also possible that there are perfectly usable ways
> to keep bikes and bike seats dry where Christoph works, but that he prefers
> not to use them because they're violating some design rule.

Depends on how you understand "perfectly usable." My collegue always
carries his expensive racing bike to our office in the 3rd floor out of
fear it may get wet or stolen. But I think this is not very convenient
and I want to avoid discussions with our boss about skid marks on the
carpet and things like that. Probably that collegue would not complain
as well if he had to cast tuples to lists for counting items - you see,
people are different ;-)

-- Christoph

Paul Rubin

unread,
Nov 30, 2005, 1:10:03 AM11/30/05
to
Mike Meyer <m...@mired.org> writes:
> But a programming language (or UI) is not just a collection of syntax
> and and interfaces - it's an implementation. You need to keep in mind
> that "practicality beats purity".

An awful lot of the time in this newsgroup, "practicality beats
purity" translates as "the programmer can just be a lazy slob".

> If following POLA makes the implementation an order of magnitude
> slower or larger, then you don't follow POLA - at least until you
> can do it without that cost.

If following POLA costs that much, at least in the kinds of examples
we talk about all the time here, something is probably wrong with the
implementation (or the design) to begin with.

Mike Meyer

unread,
Nov 30, 2005, 1:33:14 AM11/30/05
to
Paul Rubin <http://phr...@NOSPAM.invalid> writes:
> Mike Meyer <m...@mired.org> writes:
>> But a programming language (or UI) is not just a collection of syntax
>> and and interfaces - it's an implementation. You need to keep in mind
>> that "practicality beats purity".
> An awful lot of the time in this newsgroup, "practicality beats
> purity" translates as "the programmer can just be a lazy slob".

You post that as if it were a bad thing.

>> If following POLA makes the implementation an order of magnitude
>> slower or larger, then you don't follow POLA - at least until you
>> can do it without that cost.
> If following POLA costs that much, at least in the kinds of examples
> we talk about all the time here, something is probably wrong with the
> implementation (or the design) to begin with.

True, but not constructive. Knowing that something is wrong is
easy. Diagnosing the problem is harder. Curing it is even harder. And
unti you get to that last step, you haven't done anything to improve
the situation.

Paul Rubin

unread,
Nov 30, 2005, 1:45:56 AM11/30/05
to
Mike Meyer <m...@mired.org> writes:
> > An awful lot of the time in this newsgroup, "practicality beats
> > purity" translates as "the programmer can just be a lazy slob".
>
> You post that as if it were a bad thing.

Yes. The idea of using a program that someone else wrote, is that
they do the work so I don't have to. If their doing less work means
that I have to do more, the program isn't as good as it might be.

A program like Python intended for wide distribution and use by large
numbers of people whose needs aren't known in advance, should do as
much to help its users as development resources allow.

Are you familiar with R. Gabriel's piece "Worse is better"? That's
not what I see "practicality beats purity" as being intended to mean.

> > If following POLA costs that much, at least in the kinds of examples
> > we talk about all the time here, something is probably wrong with the
> > implementation (or the design) to begin with.
>
> True, but not constructive. Knowing that something is wrong is
> easy. Diagnosing the problem is harder. Curing it is even harder.

Look at the list.count() example at the start of this thread.
Diagnosing it isn't hard. Curing it isn't hard. It doesn't bloat
Python by an order of magnitude. A suitably factored implementation
might handle lists and strings with the exact same code and not incur
any extra cost at all. That type of thing happens all the time here.

bon...@gmail.com

unread,
Nov 30, 2005, 1:57:44 AM11/30/05
to

Paul Rubin wrote:
> Look at the list.count() example at the start of this thread.
> Diagnosing it isn't hard. Curing it isn't hard. It doesn't bloat
> Python by an order of magnitude. A suitably factored implementation
> might handle lists and strings with the exact same code and not incur
> any extra cost at all. That type of thing happens all the time here.
I believe the language creator use the "lack of" as a way to
prevent/discourage that kind of usage. Just like the ternary
operator(still don't know why it is finally accepted). It is not a
problem(not having), it is a feature(to teach you program better), so
what cure are we talking about ?

Antoon Pardon

unread,
Nov 30, 2005, 5:28:37 AM11/30/05
to
On 2005-11-29, Bengt Richter <bo...@oz.net> wrote:
> On 29 Nov 2005 08:27:43 GMT, Antoon Pardon <apa...@forel.vub.ac.be> wrote:
>
>>On 2005-11-28, Duncan Booth <duncan...@invalid.invalid> wrote:
>>> Antoon Pardon wrote:
>>>
>>>>
>>>> No I gave an example, you would implement differently. But even
>>>> if you think my example is bad, that would make it a bad argument
>>>> for tuples having list methods. That is not the same as being
>>>> a good argument against tuples having list methods.
>>>
>>> Tuples don't have list methods, therefore any code which seems to require a
>>> tuple with list methods should make you stop and consider whether your
>>> design is wrong.
>>
>>IMO that is a non-sequitur, because that makes what is good or bad
>>design dependand on the language used.
>>
>>If I have a design that seems to require tuples with a count method,
>>then wether that is a good or bad design doesn't depend on
>>whether or not python allows that or not.
>>
> No, but if your requirement is to count __eq__ - matching items in a
> tuple, maybe your sense of orthogonality ought to abstract out the
> sequence aspect in some other way than seeing it as a seeming method
> requirement for tuple. A tuple.count method has implications about
> attribute access to a special object, tuple, which then you have
> to deal with for every new object you introduce, unless you want to
> inherit it from object, but that means object becomes a
> mega swiss army knife in short order.

I'm open too other possibilties, and I'm interrested in your iterator
methods. It is just that on the one hand people talk about the
advantages of tuples as keys, (no need to copy the keys, since
they are immutable) while on the other hand when tuples lack
some functionality tell me to cast them as lists, completely
eliminating the adavantage tuples have.

> So IMO the thing is not to ask for a specific solution like "why
> not a count method for tuples?" You'll just get answers to that literal
> question, with some elaborations. Instead, if you put it in the form
> of what your general requirement really is (I'm guessing ;-) which I
> assume is to be able to apply list count method _functionality_ to
> anything which quacks like a list, including tuples etc. In short,
> anything iterable.

Sure, A base sequence type, from which tuples and lists would inherit
that would provide for this functionality would be good too. Of
course it isn't that difficult to write a general function that works
on any iterable either.

> Now the problem is to bring program and data together with some
> spelling in python. data.method() is certainly one spelling, but
> so is method(data). You gain something either way. The first allows
> you to associate the method and data without executing the method, i.e.,
> data.method is a bound method object that has the data-method association
> built in, and it can be passed around.

There are other ways to get a bound method like object, so I don't
consider that a big advantage.

> method(data) does the call right
> away and uses a diferent name space search path to find method, and is
> not necessarily associated with type(data). To ask for common methods
> for all objects that exhibit some similar aspect is to entangle their
> types in some way or to duplicate stuff. Sometimes it's fine to
> derive from a common base etc., but
>
> why not a built-in count function that does something like (untested)
>
> def count(obj, match_item, eq=operator.eq):
> return sum(1 for item in iter(obj) if eq(item, match_item))

Sure. The problem here is a bit about python only providing a partial
solution. If python didn't provide any count methods I think nobody
would have complained. If you needed this, you could easily provide
it your self.

But now python does provide it, but not for all classes it seems
applyable to, so people question why.

> which would give a little flexibility about eq comparison as well as
> wide applicability to any sequence? index too (untested)
>
> def index(obj, match_item, eq=operator.eq):
> try: return (i for i, item in enumerate(obj) if eq(item, match_item)).next()
> except StopIteration: raise ValueError('index(seq, item): item not in seq')
>
> why doesn't list have a find like str? ;-)
>
> def find(obj, match_item, eq=operator.eq):
> try: return (i for i, item in enumerate(obj) if eq(item, match_item)).next()
> except StopIteration: return -1
>
> One could create an alternate spelling for obj.count(thing) using the count function above.
> You can spell it now as
>
> count.__get__(obj, type(obj))(thing)
>
> if you want to duplicate the effect of having the count function retrieved from type(obj)
> as if it were a method defined there. Or you can spell it
>
> count(obj)
>
> which doesn't seem too bad ;-)
> But now the problem is cluttering the __builtins__ space. So maybe it would be
> better to write
> from sequence_goodies import count
> ...
> count(obj)

Sure, thanks for the suggestion, I think I'll write me a sequence module
with these and similar function. It seems just a bit stupid, because
once I wrote all of these, a number of list methods seem just a waste
that is to be carried along.

> Do you really want a count method for tuple? Or is that maybe not as clean is
> it seemed? All the issues aren't usually immediatly apparent, so IMO the more
> we focus on abstract functionality desired, the more likely we will get
> helpful solution ideas for a menu of choices, and avoid prematurely discussing
> whether we should have pumpkin pie with or without whipped cream, when finally
> we might all like strawberries and cream better, if someone had thought of it.

Well my preferred solution, would have been if sequence had been a mixin
class, that would provide a number of methods for subclasses that
provide the right protocol and then tuple and list being such a
subclass. I think that would have been more pythonic than your suggested
solution, but I think your suggestion is a valuable alternative.

--
Antoon Pardon

Mike Meyer

unread,
Nov 30, 2005, 3:15:09 PM11/30/05
to
Paul Rubin <http://phr...@NOSPAM.invalid> writes:
> Mike Meyer <m...@mired.org> writes:
>> > An awful lot of the time in this newsgroup, "practicality beats
>> > purity" translates as "the programmer can just be a lazy slob".
>> You post that as if it were a bad thing.
> Yes. The idea of using a program that someone else wrote, is that
> they do the work so I don't have to. If their doing less work means
> that I have to do more, the program isn't as good as it might be.

No, it's not as good *for your purpose* as it might be. But they
didn't write it for your purpose, they wrote it for theirs. The latter
is really the only standard of judgement.

> A program like Python intended for wide distribution and use by large
> numbers of people whose needs aren't known in advance, should do as
> much to help its users as development resources allow.

True. You seem to disagree about how they choose to allocate the
resources. The fix for that is well-known.

> Are you familiar with R. Gabriel's piece "Worse is better"? That's
> not what I see "practicality beats purity" as being intended to mean.

Why not? That seems to summarise a couple of the points in the more
successful design philosophy, most notably:

The design most not be overly inconsistent.
The design must cover as many important situations as is practical.

If these don't reflet what you think "Practicality beats purity"
means, then what do you think it means?

Actually, I've been thinking about that bit recently, and noting that
a number of things from "import this" seem to espouse the more
successful approach from that section:

Simple is better than complex.
Complex is better than complicated.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

>> > If following POLA costs that much, at least in the kinds of examples
>> > we talk about all the time here, something is probably wrong with the
>> > implementation (or the design) to begin with.
>> True, but not constructive. Knowing that something is wrong is
>> easy. Diagnosing the problem is harder. Curing it is even harder.
> Look at the list.count() example at the start of this thread.
> Diagnosing it isn't hard. Curing it isn't hard. It doesn't bloat
> Python by an order of magnitude.

Did somebody actually use "Practicality beats purity" as an excuse for
not making list.count and string.count have the same arguments? If so,
I missed it. I certainly don't agree with that - count ought to work
right in this case.

> A suitably factored implementation might handle lists and strings
> with the exact same code and not incur any extra cost at all. That
> type of thing happens all the time here.

If it happens all the time, you shouldn't have any trouble nameing a
number of things that a majority of users think are misfeatures that
aren't being fixed. Could you do that?

Christoph Zwerschke

unread,
Nov 30, 2005, 4:07:56 PM11/30/05
to

Sorry, but I still do not get it. Why is it a feature if I cannot count
or find items in tuples? Why is it bad program style if I do this? So
far I haven't got any reasonable explanation and I think there is no.

-- Christoph

bon...@gmail.com

unread,
Nov 30, 2005, 8:57:20 PM11/30/05
to
I have no idea, I can understand their view, not necessarily agree. And
reasonable explanation is not something I usually find on this group,
for issues like this.

Chris Mellon

unread,
Nov 30, 2005, 9:46:39 PM11/30/05
to pytho...@python.org


I'd have to say this:

First, remember that while your idea is obvious and practical and
straightforward to you, everybodys crummy idea is like that to them.
And while I'm not saying your idea is crummy, bear in mind that not
everyone is sharing your viewpoint.

If you want to make changes to the language, you need to be prepared
to convince other people that your idea really is a good one.
Therefore:

Be prepared to present a use case. If your idea really is
straightforward, simple, and obvious this should be fairly easy. It is
possible that your idea is so simple and obvious that everyone will
agree with it, do not expect this to be the case no matter how simple
and obvious it seems to you.

Be prepared to defend your use case. If people show reasons why your
use case is invalid, be prepared to consider that you may be wrong. If
you're still sure that you aren't, present a different use case -
don't expect other people to imagine one for you.

If you *really* want a language feature changed, be prepared to
present a patch for it. If you aren't willing or able to implement it
yourself, you must convince someone else that not only is your change
a good idea, but that it's a good enough idea that they should work on
it, which is always more of an uphill battle.

There may be different subjective or conceptual reasonings at work -
like you wanting to treat tuples as first class sequences while others
(like Guido) want to treat them otherwise. There's no right answer in
a subjective argument, so be prepared to present practical support,
and, unless you're the BDFL, be prepared to be ignored. If it bothers
you enough, you know what your options are.

Chris Mellon

unread,
Dec 1, 2005, 12:16:46 AM12/1/05
to

Donn Cave

unread,
Dec 1, 2005, 2:13:44 AM12/1/05
to
Quoth bon...@gmail.com:
| Christoph Zwerschke wrote:
...

|> Sorry, but I still do not get it. Why is it a feature if I cannot count
|> or find items in tuples? Why is it bad program style if I do this? So
|> far I haven't got any reasonable explanation and I think there is no.
|
| I have no idea, I can understand their view, not necessarily agree. And
| reasonable explanation is not something I usually find on this group,
| for issues like this.

It's hard to tell from this how well you do understand it, and of
course it's hard to believe another explanation is going to make
any difference to those who are basically committed to the opposing
point of view. But what the hell.

Tuples and lists really are intended to serve two fundamentally different
purposes. We might guess that just from the fact that both are included
in Python, in fact we hear it from Guido van Rossum, and one might add
that other languages also make this distinction (more clearly than Python.)

As I'm sure everyone still reading has already heard, the natural usage
of a tuple is as a heterogenous sequence. I would like to explain this
using the concept of an "application type", by which I mean the set of
values that would be valid when applied to a particular context. For
example, os.spawnv() takes as one of its arguments a list of command
arguments, time.mktime() takes a tuple of time values. A homogeneous
sequence is one where a and a[x:y] (where x:y is not 0:-1) have
the same application type. A list of command arguments is clearly
homogeneous in this sense - any sequence of strings is a valid input,
so any slice of this sequence must also be valid. (Valid in the type
sense, obviously the value and thus the result must change.) A tuple
of time values, though, must have exactly 9 elements, so it's heterogeneous
in this sense, even though all the values are integer.

One doesn't count elements in this kind of a tuple, because it's presumed
to have a natural predefined number of elements. One doesn't search for
values in this kind of a tuple, because the occurrence of a value has
meaning only in conjunction with its location, e.g., t[4] is how many
minutes past the hour, but t[5] is how many seconds, etc.

I have to confess that this wasn't obvious to me, either, at first, and
in fact probably about half of my extant code is burdened with the idea
that a tuple is a smart way to economize on the overhead of a list.
Somewhere along the line, I guess about 5 years ago? maybe from reading
about it here, I saw the light on this, and since then my code has gotten
easier to read and more robust. Lists really are better for all the
kinds of things that lists are for -- just for example, [1] reads a lot
better than (1,) -- and the savings on overhead is not worth the cost to
exploit it. My tendency to seize on this foolish optimization is however
pretty natural, as is the human tendency to try to make two similar things
interchangeable. So we're happy to see that tuple does not have the
features it doesn't need, because it helps in a small way to make Python
code better. If only by giving us a chance to have this little chat once
in a while.

Donn Cave, do...@drizzle.com

Ben Finney

unread,
Dec 1, 2005, 2:34:58 AM12/1/05
to
Donn Cave <do...@drizzle.com> wrote:
> Tuples and lists really are intended to serve two fundamentally
> different purposes.
> [...]

> As I'm sure everyone still reading has already heard, the natural
> usage of a tuple is as a heterogenous sequence. [...] A list of

> command arguments is clearly homogeneous in this sense - any
> sequence of strings is a valid input, so any slice of this sequence
> must also be valid. (Valid in the type sense, obviously the value
> and thus the result must change.) A tuple of time values, though,
> must have exactly 9 elements, so it's heterogeneous in this sense,
> even though all the values are integer.
>
> I have to confess that this wasn't obvious to me, either, at first,
> and in fact probably about half of my extant code is burdened with
> the idea that a tuple is a smart way to economize on the overhead of
> a list. Somewhere along the line, I guess about 5 years ago? maybe
> from reading about it here, I saw the light on this, and since then
> my code has gotten easier to read and more robust.

Strangely, I learned this as I was learning the language, and
understood it after reading the explanation a couple of times (I can't
remember where I was reading it, but it must have been a decent
guide).

However, in the intervening time I'd forgotten this fundamental
difference between the *purpose* of list and tuple.

Thanks very much for this reminder. You've probably stopped me from
writing a bunch of misguided code and realising 5 years too late :-)

--
\ "Timid men prefer the calm of despotism to the boisterous sea |
`\ of liberty." -- Thomas Jefferson |
_o__) |
Ben Finney

Mike Meyer

unread,
Dec 1, 2005, 2:37:49 AM12/1/05
to
"Donn Cave" <do...@drizzle.com> writes:
> Tuples and lists really are intended to serve two fundamentally different
> purposes. We might guess that just from the fact that both are included
> in Python, in fact we hear it from Guido van Rossum, and one might add
> that other languages also make this distinction (more clearly than Python.)
>
> As I'm sure everyone still reading has already heard, the natural usage
> of a tuple is as a heterogenous sequence. I would like to explain this
> using the concept of an "application type", by which I mean the set of
> values that would be valid when applied to a particular context. For
> example, os.spawnv() takes as one of its arguments a list of command
> arguments, time.mktime() takes a tuple of time values. A homogeneous
> sequence is one where a and a[x:y] (where x:y is not 0:-1) have
> the same application type. A list of command arguments is clearly
> homogeneous in this sense - any sequence of strings is a valid input,
> so any slice of this sequence must also be valid. (Valid in the type
> sense, obviously the value and thus the result must change.) A tuple
> of time values, though, must have exactly 9 elements, so it's heterogeneous
> in this sense, even though all the values are integer.
>
> One doesn't count elements in this kind of a tuple, because it's presumed
> to have a natural predefined number of elements. One doesn't search for
> values in this kind of a tuple, because the occurrence of a value has
> meaning only in conjunction with its location, e.g., t[4] is how many
> minutes past the hour, but t[5] is how many seconds, etc.

I get all that, I really do. I would phrase it as "a tuple is a set of
attributes that happen to be named by integers." count doesn't make
sense on the attributes of an object - so it doesn't make sense on a
tuple. index doesn't make sense on the attributes of an object - so it
doesn't make sense on a tuple. A loop over the attributes of an object
doesn't make sense - so it doesn't make sense on a tuple.

So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?

Seriously. Why doesn't this have to be phrased as "for x in list((1,
2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?

bon...@gmail.com

unread,
Dec 1, 2005, 2:55:52 AM12/1/05
to

Mike Meyer wrote:
> I get all that, I really do. I would phrase it as "a tuple is a set of
> attributes that happen to be named by integers." count doesn't make
> sense on the attributes of an object - so it doesn't make sense on a
> tuple. index doesn't make sense on the attributes of an object - so it
> doesn't make sense on a tuple. A loop over the attributes of an object
> doesn't make sense - so it doesn't make sense on a tuple.
>
> So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?
>
> Seriously. Why doesn't this have to be phrased as "for x in list((1,
> 2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?
>
I don't know what you use tuple for, but I do need to loop over
attributes of an object(be it tuple or dict or even set), though no
need for count(), index(), not even on list, so far.

I think why people may ask for .count() and .index() for tuple is that
if I am writing a generic function that receive such a thing, I don't
need to do a type check or try/except block, should the caller tries to
be smart and use tuple instead of list(say for optimization reason).

Fredrik Lundh

unread,
Dec 1, 2005, 3:09:41 AM12/1/05
to pytho...@python.org
Mike Meyer wrote:

> So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?

because the syntax says so:

http://docs.python.org/ref/for.html

> Seriously. Why doesn't this have to be phrased as "for x in list((1,
> 2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?

because anything that supports [] can be iterated over.

</F>

Ed Singleton

unread,
Dec 1, 2005, 4:26:26 AM12/1/05
to pytho...@python.org

If you're leaving skid marks on the floor, maybe you need better underwear?

http://www.google.co.uk/search?q=skid+marks+slang

Sorry to lower the tone.

Ed

Christoph Zwerschke

unread,
Dec 1, 2005, 4:38:53 AM12/1/05
to
Donn Cave schrieb:

> As I'm sure everyone still reading has already heard, the natural usage
> of a tuple is as a heterogenous sequence. I would like to explain this
> using the concept of an "application type", by which I mean the set of
> values that would be valid when applied to a particular context. For
> example, os.spawnv() takes as one of its arguments a list of command
> arguments, time.mktime() takes a tuple of time values. A homogeneous
> sequence is one where a and a[x:y] (where x:y is not 0:-1) have
> the same application type. A list of command arguments is clearly
> homogeneous in this sense - any sequence of strings is a valid input,
> so any slice of this sequence must also be valid. (Valid in the type
> sense, obviously the value and thus the result must change.) A tuple
> of time values, though, must have exactly 9 elements, so it's heterogeneous
> in this sense, even though all the values are integer.

I understand what you want to say, but I would not use the terms
"homogenuous" or "heterogenous" since their more obvious meaning is that
all elements of a collection have the same type.

What you are calling an "application type" is a range of values, and the
characteristic you are describing is that the range of values is not
left when you slice (or extend) an object. So what you are describing is
simply a slicable/extendable application type. It is obvious that you
would use lists for this purpose, and not tuples, I completely agree
with you here. But this is just a consequence of the immutability of
tuples which is their more fundamental characteristic.

Let me give an example: Take all nxn matrices as your application type.
That applicaiton type is clearly not slicable/extendable, because this
would change the dimension, thus not "heterogenous" in your definition.

So would you use tuples (of tuples) or lists (of lists) here? Usually
you will use lists, because you want to be able to operate on the
matrices and transform them in place. So you see the more fundamental
characteristic and reason for prefering lists over tuples is mutability.

Let us assume you want to calculate the mathematical rank of such a
matrix. You would bring it in upper echelon shape (here, you are
operating on the rows, thus you would use lists) and then you would
count the all-zero rows. Ok, this is not an example for using count() on
tuples, but it is an example for using count() on a "heterogenous"
collection in your definition.

I completely agree that you will need count() and item() much less
frequently on tuples because of their immutability. This is obvious.
(Tuples themselves are already used less frequently than lists for this
reason.) But I still cannot see why you would *never* use it or why it
would be bad style.

And I don't understand why those who smile at my insistence on design
principles of consistence - propagating practicability instead - are
insisting themselves on some very philosophical and non-obvious design
principles or characteristics of tuples.

-- Christoph

Fredrik Lundh

unread,
Dec 1, 2005, 4:55:48 AM12/1/05
to pytho...@python.org
Christoph Zwerschke wrote:

> I understand what you want to say, but I would not use the terms
> "homogenuous" or "heterogenous" since their more obvious meaning is that
> all elements of a collection have the same type.

http://www.google.com/search?q=duck+typing

</F>

Antoon Pardon

unread,
Dec 1, 2005, 5:11:56 AM12/1/05
to

I don't agree with this. Something can be a hetergenous sequence, but
the order can be arbitrary, so that any order of the elements can work
as long as at is well defined beforehand. Points on a 2D latice are
by convention notated as (x,y) but (y,x) works just as well. When
working in such a lattice it is possible to be interested in those
points that lay on one of the axes. Since the X-axis and the Y-axis
play a symmetrical role, it is possible that it doesn't matter which
axis the point is on. So counting how many of the coordinates are
zero is natural way to check if a point is on an axe. Doing a find
is a natural way to check if a point is on an axis and at the same
time find out which one.

So that a sequence is heterogenous in this sense doesn't imply
that count, find and other methods of such kind don't make sense.

--
Antoon Pardon

Antoon Pardon

unread,
Dec 1, 2005, 5:25:59 AM12/1/05
to

This just begs the question. If tuples are supposed to be such
heterogenous sequences, one could indeed question why they
support [].

And even if good arguments are given why tuples shouls support
[], the fact that the intention of tuples and list are so
different casts doubts on the argument that supporting []
is enough reason to support iteration.

One could equally also argue that since iteration is at the heart
of methods like index, find and count, that supporting iteration
is sufficient reason to support these methods.

--
Antoon Pardon

Christoph Zwerschke

unread,
Dec 1, 2005, 6:02:25 AM12/1/05
to
I think this all boils down to the following:

* In their most frequent use case where tuples are used as lightweight
data structures keeping together heterogenous values (values with
different types or meanings), index() and count() do not make much sense.

I completely agree that his is the most frequent case. Still there are
cases where tuples are used to keep homogenous values together (for
instance, RGB values, points in space, rows of a matrix). In these cases
it would be principally useful to have index() and count() methods.

But:

* Very frequently you will use only 2- or 3-tuples, where direct queries
may be faster than item() and count(). (That's probably why Antoon's RGB
example was rejected as use case though it was principally a good one).

* Very frequently you want to perform operations on these objects and
change their elements, so you would use lists instead of tuples anyway.
See my use case where you would determine whether a vector is zero by
count()ing its zero entries or the rank of a matrix by count()ing zero rows.

* You will use item() and count() in situations where you are dealing
with a small discrete range of values in your collection. Often you will
use strings instead of tuples in these cases, if you don't need to sum()
the items, for instance.

So, indeed, very few use cases will remain if you filter throught the
above. But this does not mean that they do not exist. And "special cases
aren't special enough to break the rules." It should be easy to imagine
use cases now.

Take for example, a chess game. You are storing the pieces in a
64-tuple, where every piece has an integer value corresponding to its
value in the game (white positive, black negative). You can approximate
the value of a position by building the sum(). You want to use the tuple
as a key for a dictionary of stored board constellations (e.g. an
opening dictionary), therefore you don't use a list.

Now you want to find the field where the king is standing. Very easy
with the index() method. Or you want to find the number of pawns on the
board. Here you could use the count() method.

-- Christoph

Fredrik Lundh

unread,
Dec 1, 2005, 6:31:48 AM12/1/05
to pytho...@python.org
Christoph Zwerschke wrote:

> It should be easy to imagine use cases now.
>
> Take for example, a chess game. You are storing the pieces in a
> 64-tuple, where every piece has an integer value corresponding to its
> value in the game (white positive, black negative). You can approximate
> the value of a position by building the sum(). You want to use the tuple
> as a key for a dictionary of stored board constellations (e.g. an
> opening dictionary), therefore you don't use a list.
>
> Now you want to find the field where the king is standing. Very easy
> with the index() method. Or you want to find the number of pawns on the
> board. Here you could use the count() method.

now, I'm no expert on data structures for chess games, but I find it hard to
believe that any chess game implementer would use a data structure that re-
quires linear searches for everything...

</F>

Christoph Zwerschke

unread,
Dec 1, 2005, 6:37:03 AM12/1/05
to
Chris Mellon schrieb:

> First, remember that while your idea is obvious and practical and
> straightforward to you, everybodys crummy idea is like that to them.
> And while I'm not saying your idea is crummy, bear in mind that not
> everyone is sharing your viewpoint.

That's completely ok. What I wanted to know is *why* people do not share
my viewpoint and whether I can understand their reasons. Often, there
are good reasons that I do understand after some discussion. In this
case, there were some arguments but they were not convincing for me.

I think the rest of your arguments have been already discussed in this
thread. People seem to have different opinions here.

-- Christoph

Christoph Zwerschke

unread,
Dec 1, 2005, 6:54:16 AM12/1/05
to
Fredrik Lundh wrote:

> Christoph Zwerschke wrote:
> now, I'm no expert on data structures for chess games, but I find it hard to
> believe that any chess game implementer would use a data structure that re-
> quires linear searches for everything...

Using linear arrays to represent chess boards is pretty common in
computer chess. Often, the array is made larger than 64 elements to make
sure moves do not go off the board but hit unbeatable pseudo pieces
standing around the borders. But in principle, linear arrays of that
kind are used, and for good reasons.

I already feared that a discussion about the details and efficiency of
this implementation would follow. But this was not the point here.

-- Christoph

Steve Holden

unread,
Dec 1, 2005, 7:13:00 AM12/1/05
to pytho...@python.org
Antoon Pardon wrote:
> On 2005-12-01, Fredrik Lundh <fre...@pythonware.com> wrote:
>
>>Mike Meyer wrote:
>>
>>
>>>So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?
>>
>>because the syntax says so:
>>
>> http://docs.python.org/ref/for.html
>>
>>
>>>Seriously. Why doesn't this have to be phrased as "for x in list((1,
>>>2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?
>>
>>because anything that supports [] can be iterated over.
>
>
> This just begs the question. If tuples are supposed to be such
> heterogenous sequences, one could indeed question why they
> support [].
>
Presumably because it's necessary to extract the individual values
(though os.stat results recently became addressable by attribute name as
well as by index, and this is an indication of the originally intended
purpose of tuples).

> And even if good arguments are given why tuples shouls support
> [], the fact that the intention of tuples and list are so
> different casts doubts on the argument that supporting []
> is enough reason to support iteration.
>
> One could equally also argue that since iteration is at the heart
> of methods like index, find and count, that supporting iteration
> is sufficient reason to support these methods.
>

One could even go so far as to prepare a patch to implement the required
methods and see if it were accepted (though wibbling is a much easier
alternative). Personally I find the collective wisdom of the Python
developers, while not infallible, a good guide as to what's pythonistic
and what's not. YMMV.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Steve Holden

unread,
Dec 1, 2005, 7:21:11 AM12/1/05
to pytho...@python.org
Christoph Zwerschke wrote:
> I think this all boils down to the following:
>
> * In their most frequent use case where tuples are used as lightweight
> data structures keeping together heterogenous values (values with
> different types or meanings), index() and count() do not make much sense.
>
> I completely agree that his is the most frequent case. Still there are
> cases where tuples are used to keep homogenous values together (for
> instance, RGB values, points in space, rows of a matrix). In these cases
> it would be principally useful to have index() and count() methods.
>
Why? Why does it make sense to ask whether an RGB color has a particular
value for one of red, green or blue? Why does it make sense to ask how
many elements there are in an RGB color? It doesn't, so you must be
talking about (ordered) *collections* of such items.

If you want a list of RGB colors then use a list. If you want a list of
points in space then use a list. Why is a tuple preferable? [If the
answer is "because a tuple can't be changed" go to the bottom of the class].

> But:
>
> * Very frequently you will use only 2- or 3-tuples, where direct queries
> may be faster than item() and count(). (That's probably why Antoon's RGB
> example was rejected as use case though it was principally a good one).
>
> * Very frequently you want to perform operations on these objects and
> change their elements, so you would use lists instead of tuples anyway.
> See my use case where you would determine whether a vector is zero by
> count()ing its zero entries or the rank of a matrix by count()ing zero rows.
>
> * You will use item() and count() in situations where you are dealing
> with a small discrete range of values in your collection. Often you will
> use strings instead of tuples in these cases, if you don't need to sum()
> the items, for instance.
>
> So, indeed, very few use cases will remain if you filter throught the
> above. But this does not mean that they do not exist. And "special cases
> aren't special enough to break the rules." It should be easy to imagine
> use cases now.
>
> Take for example, a chess game. You are storing the pieces in a
> 64-tuple, where every piece has an integer value corresponding to its
> value in the game (white positive, black negative). You can approximate
> the value of a position by building the sum(). You want to use the tuple
> as a key for a dictionary of stored board constellations (e.g. an
> opening dictionary), therefore you don't use a list.
>

This is a pretty bogus use case. Seems to me like a special case it's
not worth breaking the rules for!

> Now you want to find the field where the king is standing. Very easy
> with the index() method. Or you want to find the number of pawns on the
> board. Here you could use the count() method.
>

Bearing in mind the (likely) performance impact of using these items as
dict keys don't you think some other representation would be preferable?

Fredrik Lundh

unread,
Dec 1, 2005, 7:31:06 AM12/1/05
to pytho...@python.org
Christoph Zwerschke wrote:

>> Christoph Zwerschke wrote:
>> now, I'm no expert on data structures for chess games, but I find it hard to
>> believe that any chess game implementer would use a data structure that re-
>> quires linear searches for everything...
>
> Using linear arrays to represent chess boards is pretty common in
> computer chess. Often, the array is made larger than 64 elements to make
> sure moves do not go off the board but hit unbeatable pseudo pieces
> standing around the borders. But in principle, linear arrays of that
> kind are used, and for good reasons.

really? a quick literature search only found clever stuff like bitboards,
pregenerated move tables, incremental hash algorithms, etc. the kind
of stuff you'd expect from a problem domain like chess.

> I already feared that a discussion about the details and efficiency of
> this implementation would follow. But this was not the point here.

so pointing out that the use case you provided has nothing to do with
reality is besides the point ? you're quickly moving into kook-country
here.

</F>

Steve Holden

unread,
Dec 1, 2005, 7:52:41 AM12/1/05
to pytho...@python.org
Mike Meyer wrote:
> Paul Rubin <http://phr...@NOSPAM.invalid> writes:
[...]

> Did somebody actually use "Practicality beats purity" as an excuse for
> not making list.count and string.count have the same arguments? If so,
> I missed it. I certainly don't agree with that - count ought to work
> right in this case.
>
I agree that the two methods are oddly inconsonant. But then since the
introduction of the "has substring" meaning for the "in" operator,
strings and lists are also inconsistent over that operation.

>
>>A suitably factored implementation might handle lists and strings
>>with the exact same code and not incur any extra cost at all. That
>>type of thing happens all the time here.
>

I don't think this would make much sense in present-day Python, mostly
because there's no such thing as a character, only a string of length
one. So a string is actually a sequence of sequences of length one. I
guess this is one of those cases where practicality beat purity. It's as
though an indexing operation on a list got you a list of length one
rather than the element at that index. Strings have always been
anomalous in this respect.

>
> If it happens all the time, you shouldn't have any trouble nameing a
> number of things that a majority of users think are misfeatures that
> aren't being fixed. Could you do that?
>

Doubtless he could. Paul's a smart guy. The missing element will be
unanimity on the rationale.

Chris Mellon

unread,
Dec 1, 2005, 7:58:44 AM12/1/05
to pytho...@python.org

This really looks to me like you have your priorities inverted.
Practically everything you want to do with this structure is
list-like, so why not make it a list and convert it to a tuple when
you need to use it as an index? Even better, since you're doing a lot
of list operations, why not make it a list and define unique IDs or
something to use as indices?

A minor change in your design/thinking (not trying to use a tuple as a
frozen list) instead of a change in the language (making tuples more
like frozen lists) seems to be the warranted solution. But maybe thats
just me.


> Now you want to find the field where the king is standing. Very easy
> with the index() method. Or you want to find the number of pawns on the
> board. Here you could use the count() method.
>
> -- Christoph

> --
> http://mail.python.org/mailman/listinfo/python-list
>

Christoph Zwerschke

unread,
Dec 1, 2005, 8:57:45 AM12/1/05
to
Steve Holden wrote:

> Christoph Zwerschke wrote:
>> I completely agree that his is the most frequent case. Still there are
>> cases where tuples are used to keep homogenous values together (for
>> instance, RGB values, points in space, rows of a matrix). In these
>> cases it would be principally useful to have index() and count() methods.
>>
> Why? Why does it make sense to ask whether an RGB color has a particular
> value for one of red, green or blue? Why does it make sense to ask how
> many elements there are in an RGB color? It doesn't, so you must be
> talking about (ordered) *collections* of such items.
>
> If you want a list of RGB colors then use a list. If you want a list of
> points in space then use a list. Why is a tuple preferable? [If the
> answer is "because a tuple can't be changed" go to the bottom of the
> class].

I cannot follow you here. How would you store RGB values? I think they
are a perfect use case for tuples in the spirit of Guido's "lightweight
C structs." So, in the spirit of Guido I would store them as tuples, or
return them as tuples by a function getpixel(x,y). Why should I not be
allowed to check for getpixel(xy).count(0) == n for black pixels in an
image with n layers? Yes, you could set BLACK=(0,)*n and test against
BLACK. You can always do things differently.

>> Take for example, a chess game. You are storing the pieces in a
>> 64-tuple, where every piece has an integer value corresponding to its
>> value in the game (white positive, black negative). You can
>> approximate the value of a position by building the sum(). You want to
>> use the tuple as a key for a dictionary of stored board constellations
>> (e.g. an opening dictionary), therefore you don't use a list.
>>
> This is a pretty bogus use case. Seems to me like a special case it's
> not worth breaking the rules for!

I already explained why use cases for count() and index() on tuples will
principally be rare. So it will always be easy for you to call them
"special cases". But they are there, and they make sense.

Also, we are not talking about "breaking" a rule or any existing code
here, but about generalizing or *broadening* a rule. (What do you do if
a rule itself is broken?)

Here is another example illustrating the problem - coincidentally, from
Fredrik's blog, http://effbot.org/zone/image-histogram-optimization.htm
(found it when googling for getpixel):

def histogram4(image):
# wait, use the list.count operator
data = list(image.getdata())
result = []
for i in range(256):
result.append(data.count(i))
return result

Here, we could imagine the getdata() method returning a tuple. Again,
why must it be casted to a list, just to use count()? In reality,
getdata() returns a sequence. But again, wouldn't it be nice if all
sequences provided count() and index() methods? Then there would be no
need to create a list from the sequence before counting.

-- Christoph

Aahz

unread,
Dec 1, 2005, 9:38:09 AM12/1/05
to
[Since part of my post seems to have gotten lost in this thread, I
figured I would repeat it]

In article <dmdrch$jms$1...@panix1.panix.com>, Aahz <aa...@pythoncraft.com> wrote:
>In article <dmdlhj$87b$1...@online.de>,
>Christoph Zwerschke <ci...@online.de> wrote:
>>
>>Or, another example, the index() method has start and end parameters for
>>lists and strings. The count() method also has start and end parameters
>>for strings. But it has no such parameters for lists. Why?
>
>That's a fair cop. Submit a patch and it'll probably get accepted.

This is one of those little things that happens in language evolution;
not everything gets done right the first time. But Python is developed
by volunteers: if you want this fixed, the first step is to submit a bug
report on SF (or go ahead and submit a patch if you have the expertise).
(I'm quite comfortable channeling Guido and other developers in saying a
patch will get accepted.)
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"Don't listen to schmucks on USENET when making legal decisions. Hire
yourself a competent schmuck." --USENET schmuck (aka Robert Kern)

Christoph Zwerschke

unread,
Dec 1, 2005, 9:41:26 AM12/1/05
to
Fredrik Lundh wrote:
>>>Christoph Zwerschke wrote:
>>Using linear arrays to represent chess boards is pretty common in
>>computer chess. Often, the array is made larger than 64 elements to make
>>sure moves do not go off the board but hit unbeatable pseudo pieces
>>standing around the borders. But in principle, linear arrays of that
>>kind are used, and for good reasons.
>
> really? a quick literature search only found clever stuff like bitboards,
> pregenerated move tables, incremental hash algorithms, etc. the kind
> of stuff you'd expect from a problem domain like chess.

I don't know where you googled, but my sources do not say that bitboards
are the *only* possible or reasonable representation:

http://chess.verhelst.org/1997/03/10/representations/
http://en.wikipedia.org/wiki/Computer_chess#Board_representations
http://www.aihorizon.com/essays/chessai/boardrep.htm
http://www.oellermann.com/cftchess/notes/boardrep.html

Many programs still use the array representation. For example:
http://www.nothingisreal.com/cheops/
http://groups.msn.com/RudolfPosch/technicalprogamdescription1.msnw
Even GNU Chess did not use bitboards before version 5.
Here is an example in Python:
http://www.kolumbus.fi/jyrki.alakuijala/pychess.html

I did not say that there aren't more sophisticated and elaborate board
representations than linear or two-dimensional arrays. But they are the
simplest and most immediate and intuitive solution, and they have indeed
been used for a long time in the 8-bit aera. Bitboards may be more
performant, particularly if you are directly programming in assembler or
C on a 64 bit machine, but not necessarily in Python. But they are also
more difficult to handle. Which representation to use also depends on
the algorithms you are using. You wouldn't write a performant chess
engine in Python anyway. But assume you want to test a particular chess
tree pruning algorithm (that does not depend on board representation)
and write a prototype for that in Python, later making a performant
implementation in assembler. You would not care so much about the
effectivity of your board representation in the prototype, but rather
about how easy it can be handled.

I think it is telling that you have to resort to a debate about
bitboards vs. arrays in order to dismiss my simple use case for index()
and count() as "unreal".

-- Christoph

Rick Wotnaz

unread,
Dec 1, 2005, 9:58:16 AM12/1/05
to
"Donn Cave" <do...@drizzle.com> wrote in
news:11334212...@jetspin.drizzle.com:

[...]

Donn, this is a reasonable argument, and in general I don't have a
problem with the distinction between tuples and lists. I have heard
and understand the argument that the intended purpose of tuple
creation is to mimic C structs, so it seems reasonable to suppose
that one knows what was placed in them. Lists are dynamic by
nature, so you need a little more help getting information about
their current state.

However, there is at least one area where this distinction is
bogus. Lists cannot be used as dictionary keys (as it now stands).
But in practice, it is often useful to create a list of values,
cast the list to a tuple, and use that as a dictionary key. It
makes little sense to keep a list of that same information around,
so in practice, the tuple/key is the container that retains the
original information. But that tuple was dynamically created, and
it isn't always true that items were placed in it deliberately.

In other words, the fact that the key is now a tuple is unrelated
to the essential nature of tuples. Not all of the tools used in
examining lists are available to the key as a tuple, though it is
really nothing more than a frozen list.

Sure, you can cast it to a list to use the list methods, but that
requires creating objects just to throw away, which seems a little
wasteful, especially since that's what you had to do to create the
key to begin with.

I'm sure Antoon wouldn't object if lists were to be allowed as
dictionary keys, which would eliminate the multiple castings for
that situation. I wouldn't, either.

I'd extend this a little to say that tuples are (at least
potentially) created dynamically quite often in other contexts as
well, so that despite their designed intent, in practice they are
used a little differently a good bit of the time. So why not adjust
the available features to the practice?

--
rzed

Fredrik Lundh

unread,
Dec 1, 2005, 10:12:01 AM12/1/05
to pytho...@python.org
Christoph Zwerschke wrote:

> I think it is telling that you have to resort to a debate about
> bitboards vs. arrays in order to dismiss my simple use case for
> index() and count() as "unreal".

kook.

</F>

Christoph Zwerschke

unread,
Dec 1, 2005, 10:21:38 AM12/1/05
to
Aahz wrote:

> This is one of those little things that happens in language evolution;
> not everything gets done right the first time. But Python is developed
> by volunteers: if you want this fixed, the first step is to submit a bug
> report on SF (or go ahead and submit a patch if you have the expertise).
> (I'm quite comfortable channeling Guido and other developers in saying a
> patch will get accepted.)

Ok, I submitted it as feature request #1370948. I currently don't have
the time and expertise to submit a patch.

-- Christoph

Fredrik Lundh

unread,
Dec 1, 2005, 10:18:52 AM12/1/05
to pytho...@python.org
Rick Wotnaz wrote:

> I'm sure Antoon wouldn't object if lists were to be allowed as
> dictionary keys, which would eliminate the multiple castings for
> that situation. I wouldn't, either.

so what algorithm do you suggest for the new dictionary im-
plementation?

</F>

Rick Wotnaz

unread,
Dec 1, 2005, 10:35:39 AM12/1/05
to
"Fredrik Lundh" <fre...@pythonware.com> wrote in
news:mailman.1455.1133450...@python.org:

Beats the heck outta me. I seem to remember that Antoon supplied
one awhile ago (for allowing lists to serve as dictionary keys,
that is). That's why I mentioned him in the first place. I didn't
pay much attention to it at the time, and I imagine it would raise
some issues, like everything does.

I'm fairly indifferent to the idea in any case; I'm just saying I
wouldn't object if lists could function as dictionary keys. It
would save that casting step I was talking about.

--
rzed

Alex Martelli

unread,
Dec 1, 2005, 10:46:38 AM12/1/05
to
Steve Holden <st...@holdenweb.com> wrote:
...

> Presumably because it's necessary to extract the individual values
> (though os.stat results recently became addressable by attribute name as
> well as by index, and this is an indication of the originally intended
> purpose of tuples).

Yep -- "time tuples" have also become pseudo-tuples (each element can be
accessed by name as well as by index) a while ago, and I believe there's
one more example besides stats and times (but I can't recall which one).

Perhaps, if the tuple type _in general_ allowed naming the items in a
smooth way, that might help users see a tuple as "a kind of
``struct''... which also happens to be immutable". There are a few such
"supertuples" (with item-naming) in the cookbook, but I wonder if it
might not be worth having such functionality in the standard library
(for this clarification as well as, sometimes, helping the readability
of some user code).


Alex

Christoph Zwerschke

unread,
Dec 1, 2005, 11:14:27 AM12/1/05
to

Thanks.

Just to clarify: I was referring to the weakness of the argument
"tuple.count() is evil" when I wrote "telling". It was not meant
derogatory towards your person in any way - if you understood it that
way I apologize. Maybe I write in a way that can be easily
misunderstood, but I would not deliberately libel others, least of all
if it is only about a petty issue of a programming language.

-- Christoph

Fredrik Lundh

unread,
Dec 1, 2005, 11:09:14 AM12/1/05
to pytho...@python.org
Rick Wotnaz wrote:

> > Rick Wotnaz wrote:
> >
> >> I'm sure Antoon wouldn't object if lists were to be allowed as
> >> dictionary keys, which would eliminate the multiple castings for
> >> that situation. I wouldn't, either.
> >
> > so what algorithm do you suggest for the new dictionary im-
> > plementation?
>
> Beats the heck outta me. I seem to remember that Antoon supplied
> one awhile ago (for allowing lists to serve as dictionary keys,
> that is).

anyone has a pointer? all I can remember is that people have posted
various "if the key is mutated, I don't care if the value can no longer
be found" proposals (besides the usual SEP variants, of course), but
Antoon's endless stream of "I claim that it be argued that" posts
makes it easy to miss things...

</F>

Fredrik Lundh

unread,
Dec 1, 2005, 11:20:50 AM12/1/05
to pytho...@python.org
Alex Martelli wrote:

iirc, providing a python-level API to the SequenceStruct stuff
has been proposed before, and rejected.

(fwiw, I'm not sure the time and stat tuples would have been
tuples if the standard library had been designed today; the C-
level stat struct doesn't have a fixed number of members, and
the C-level time API would have been better off as a light-
weight "time" type (similar to sockets, stdio-based files, and
other C-wrapper types))

</F>

Rocco Moretti

unread,
Dec 1, 2005, 12:05:58 PM12/1/05
to

<devil's_advocate> One option is to create a new "frozen list" type, a`
la frozen sets.


People who argue that "frozen list" is not needed because we already
have the tuple type, while simultaneously arguing that tuples shouldn't
grow list methods because they are conceptually different from lists
will be bludgeoned to death with a paradox. :) </devil's_advocate>

Fredrik Lundh

unread,
Dec 1, 2005, 12:45:00 PM12/1/05
to pytho...@python.org
Rocco Moretti wrote:

>>>I'm sure Antoon wouldn't object if lists were to be allowed as
>>>dictionary keys, which would eliminate the multiple castings for
>>>that situation. I wouldn't, either.
>>
>> so what algorithm do you suggest for the new dictionary im-
>> plementation?
>
> <devil's_advocate> One option is to create a new "frozen list" type, a`
> la frozen sets.

doesn't frozenset make a copy?

> People who argue that "frozen list" is not needed because we already
> have the tuple type, while simultaneously arguing that tuples shouldn't
> grow list methods because they are conceptually different from lists
> will be bludgeoned to death with a paradox.

http://www.python.org/peps/pep-0351.html

This PEP describes a simple protocol for requesting a frozen,
immutable copy of a mutable object. It also defines a new
built-in function which uses this protocol to provide an
immutable copy on any cooperating object.
...

Here are some code samples which show the intended semantics

class xset(set):
def __freeze__(self):
return frozenset(self)

class xlist(list):
def __freeze__(self):
return tuple(self)

...

</F>

Rocco Moretti

unread,
Dec 1, 2005, 1:35:18 PM12/1/05
to
Fredrik Lundh wrote:
> Rocco Moretti wrote:
>
>>>>I'm sure Antoon wouldn't object if lists were to be allowed as
>>>>dictionary keys, which would eliminate the multiple castings for
>>>>that situation. I wouldn't, either.
>>>
>>>so what algorithm do you suggest for the new dictionary im-
>>>plementation?
>>
>><devil's_advocate> One option is to create a new "frozen list" type, a`
>>la frozen sets.
>
> doesn't frozenset make a copy?

As does the current "cast as tuple" technique. (I'm certainly not
advocating it, but ...) Certain implementations of "frozen list" could
possibly do the list->frozenlist conversion without a copy. (e.g. by
flipping an "immutable" bit)

> http://www.python.org/peps/pep-0351.html
>
> This PEP describes a simple protocol for requesting a frozen,
> immutable copy of a mutable object.

Perhaps Barry has been borrowing Guido's time machine?

Antoon Pardon

unread,
Dec 1, 2005, 2:47:02 PM12/1/05
to
On 2005-12-01, Steve Holden <st...@holdenweb.com> wrote:
> Antoon Pardon wrote:
>> On 2005-12-01, Fredrik Lundh <fre...@pythonware.com> wrote:
>>
>>>Mike Meyer wrote:
>>>
>>>
>>>>So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?
>>>
>>>because the syntax says so:
>>>
>>> http://docs.python.org/ref/for.html
>>>
>>>
>>>>Seriously. Why doesn't this have to be phrased as "for x in list((1,
>>>>2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?
>>>
>>>because anything that supports [] can be iterated over.
>>
>>
>> This just begs the question. If tuples are supposed to be such
>> heterogenous sequences, one could indeed question why they
>> support [].
>>
> Presumably because it's necessary to extract the individual values

It isn't, The stated intent of tuples seems to suggest that packing
and unpacking should be sufficient.

> (though os.stat results recently became addressable by attribute name as
> well as by index, and this is an indication of the originally intended
> purpose of tuples).
>
>> And even if good arguments are given why tuples shouls support
>> [], the fact that the intention of tuples and list are so
>> different casts doubts on the argument that supporting []
>> is enough reason to support iteration.
>>
>> One could equally also argue that since iteration is at the heart
>> of methods like index, find and count, that supporting iteration
>> is sufficient reason to support these methods.
>>
> One could even go so far as to prepare a patch to implement the required
> methods and see if it were accepted (though wibbling is a much easier
> alternative).

That has been done and it was rejected.

> Personally I find the collective wisdom of the Python
> developers, while not infallible, a good guide as to what's pythonistic
> and what's not. YMMV.

That's because their decisions will shape python and thus decide
what is pythonic and what is not.

--
Antoon Pardon

Mike Meyer

unread,
Dec 1, 2005, 3:17:26 PM12/1/05
to
"Fredrik Lundh" <fre...@pythonware.com> writes:
> Mike Meyer wrote:
>> So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?
> because the syntax says so:
> http://docs.python.org/ref/for.html

In other words, "Because that's the way we do things."

>> Seriously. Why doesn't this have to be phrased as "for x in list((1,
>> 2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?
> because anything that supports [] can be iterated over.

That's false. Anything that has __getitem__ supports []. To be
iterated over, it has to have __iter__, or an __getitem__ that works
on integers properly. Writing a class that meets the first without
meeting the second is easy. Dicts used to qualify, and tuples could be
iterated over at that time.

Not really very satisfactory reasons.

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

Donn Cave

unread,
Dec 1, 2005, 3:18:37 PM12/1/05
to
In article <mailman.1458.1133454...@python.org>,
"Fredrik Lundh" <fre...@pythonware.com> wrote:

Right. After devoting a lengthy post to the defense of
tuples as a structured type, I have to admit that they're
not a very good one - it's hard to think of many structured
values that are ideally expressed by a fixed length vector
with elements accessed by integer index.

Another theme that occasionally comes up in advice from the
learned has been "use a class". Of course for values that
are related to some external structure, you'd want to provide
something to make tuple(a) work, serialization etc., and you'd
probably end up with something a lot like StructSequence.
Meanwhile losing a significant overhead.

I wrote a quickie Python API to SequenceStruct and used it to
make an (x, y) coord type, to compare with a Coord.x,y class.
A list of a million coords used 1/5 space, and took 1/10 the
time to create. Hm.

Donn Cave, do...@u.washington.edu

Donn Cave

unread,
Dec 1, 2005, 3:28:54 PM12/1/05
to
In article <dmnahm$5m5$1...@news.doit.wisc.edu>,
Rocco Moretti <roccom...@hotpop.com> wrote:

> People who argue that "frozen list" is not needed because we already
> have the tuple type, while simultaneously arguing that tuples shouldn't
> grow list methods because they are conceptually different from lists
> will be bludgeoned to death with a paradox. :) </devil's_advocate>

Maybe I can dodge the paradox by noting that the set of things
we need, is much larger than the set of things we need enough
to do what it takes to get them. So I can agree that frozen
lists are needed, without necessarily supporting the effort.

Donn Cave, do...@u.washington.edu

Donn Cave

unread,
Dec 1, 2005, 3:46:35 PM12/1/05
to
In article <86k6epl...@bhuda.mired.org>, Mike Meyer <m...@mired.org>
wrote:
...

> So why the $*@& (please excuse my Perl) does "for x in 1, 2, 3" work?
>
> Seriously. Why doesn't this have to be phrased as "for x in list((1,
> 2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?

How could list(t) work, if for x in t didn't?
For me, conceptually, if an object can't be accessed
sequentially, then it can't be mapped to a sequence.

Anyway, it seems to me that in the end this is about
that balance between practicality and purity. Maybe
it's more like tuples have a primary intended purpose,
and some support for other applications. Not white,
but not pure black either.

Donn Cave, do...@u.washington.edu

Fredrik Lundh

unread,
Dec 1, 2005, 3:49:47 PM12/1/05
to pytho...@python.org
Mike Meyer wrote:

>>> Seriously. Why doesn't this have to be phrased as "for x in list((1,
>>> 2, 3))", just like you have to write list((1, 2, 3)).count(1), etc.?
>> because anything that supports [] can be iterated over.
>
> That's false. Anything that has __getitem__ supports []. To be
> iterated over, it has to have __iter__, or an __getitem__ that works
> on integers properly.

your arguments are getting more and more antoon-like. you can create
an iterator (using iter) for any object that supports [] (__getitem__), but
if __getitem__ doesn't do the right thing, any attempt to fetch items by
calling it will of course fail as well.

> Writing a class that meets the first without
> meeting the second is easy. Dicts used to qualify, and tuples could be
> iterated over at that time.
>
> Not really very satisfactory reasons.

that's how python's sequence protocol works. duck typing all the
way down.

http://www.google.com/search?q=duck+typing

</F>

Paul Rubin

unread,
Dec 1, 2005, 4:17:24 PM12/1/05
to
Donn Cave <do...@u.washington.edu> writes:
> Right. After devoting a lengthy post to the defense of
> tuples as a structured type, I have to admit that they're
> not a very good one ...
> Another theme that occasionally comes up in advice from the
> learned has been "use a class".

There's a historical issue too: when tuples started first being
used this way in Python, classes had not yet been introduced.

Donn Cave

unread,
Dec 1, 2005, 4:44:15 PM12/1/05
to
In article <7x64q8w...@ruckus.brouhaha.com>,

Paul Rubin <http://phr...@NOSPAM.invalid> wrote:

> There's a historical issue too: when tuples started first being
> used this way in Python, classes had not yet been introduced.

When was that, old-timer? According to Misc/HISTORY,
Python was first posted to alt.sources at version 0.9.0,
February 1991. It doesn't say 0.9.0 had classes, but
at 0.9.3 we see refinements like __dict__, and it's hard
to imagine that classes themselves snuck in without notice
in the interim.

If you got a copy of some older version than this, you
have some interesting historical perspectives there, but
not much of a historical issue, I'd say, without much
going on in the way of a user community.

Donn Cave, do...@u.washington.edu

It is loading more messages.
0 new messages