Why tuple with one item is no tuple

D

Daniel Dittmar

Diez said:
I reread his example and have to admit I'm confused: He complains about
having written his _own_ vector class - and concatenation and addition had
to use both + ?

I've interpreted it as:
If Python had choosen different operators for addition and sequence
concatenation, I could have implemented them both in my vector class. As
it is, I have to implement one of them using a non-standard operator.
The examples focus too much on numbers - if we use instead

("foo")

we would get a iterable yielding ["foo",] or - as string already supports
iteration - ['f', 'o', 'o']. Which one to chose?

What I was hinting at (NOT proposing, I'd hate this) was that integers
implement the [] operator. 5 [0] would then return 5, for all practical
purposes, it would look like a tuple. String already implements []. Yes,
that would lead to really surprising and inconsistent behaviour.
Well, the number of operators built into the language is limited - and I
actually prefer to have the possibility to overload these if I want to.
Nobody forces me - I could use

v1.concat(v2)

for two vectors v1, v2 if I wanted to.

My peeve is about having operators added to standard types. This
increases the chances that using an object the wrong way leads to a
bogus result, not a runtime error. A more common programming error I
commit is passing a string where a list ist expected. And then I wonder
why later operations work on one-character strings.

Operator overloading is certainly an irregular verb:
- I make the usage more intuitive
- Yours may lead to misinterpretation
- He obfuscates

Daniel
 
J

James Stroud

As I said: show me which parentheses to use

I kind of like the comma as a tuple "parentheses"

,1,2,3,

replacing

(1,2,3)
or
1,2,3,
or
1,2,3
or (isn't this is getting out of hand?)
(1,2,3,)

Why not--except of course for backward compatability? Comma is not used for
anything else in python as far as I know. This would be very unambiguous.
Then, the purity would manifest itself the naked comma being an empty tuple.
Think about the zen of:

,


James
 
R

Robert Kern

James said:
I kind of like the comma as a tuple "parentheses"

,1,2,3,

replacing

(1,2,3)
or
1,2,3,
or
1,2,3
or (isn't this is getting out of hand?)
(1,2,3,)

Why not--except of course for backward compatability? Comma is not used for
anything else in python as far as I know.

[1, 2, 3]
{'a': 0, 'b': 2}
f(x, y)
print foo,
This would be very unambiguous.

Not entirely.
Then, the purity would manifest itself the naked comma being an empty tuple.
Think about the zen of:

,

Is that a tuple or grit on my monitor? :)

--
Robert Kern
(e-mail address removed)

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

Antoon Pardon

Op 2005-03-16 said:
As I said: show me which parentheses to use - and keep in mind that:

- < and > are for comparisions and the same ambiguity troubles arise
- unicode surely features some usable characters (e.g. the quotation markes
that look like <<, but are one char). But for one that complains that
typing and additional comma is too much already, I doubt that having to
press some weird multi key stroke is a viable option.

Complaints about typing an extra character are not all the same.
One can complain about the extra character that is needed on
the screen and one can complain about the extra finger work
that is needed to get a specific character on the screen.

Besides I don't remember complaining about typing an extra character.
To me neither, as I
prefer my parentheses to be accessed easily, even on a vi running in a
console from a tn3270 terminal


And no way in mathematics or any other language either - if you want the
same function symbol on the same operators to have _different_ semantics,
you're getting pretty non-deterministic.

So python choose a non-deterministic direction. To me (2,3) + (4,5)
equals (6,8). I don't dispute that having an operator to combine
(2,3) and (4,5) in (2,3,4,5) is usefull, but they should never have
used the "+" for that.
Your opinion is wrong. It's because you seem to not have understood the
example: The expression (5 + 4) could be understood as 9 or as (9,). In
python (and each and every other dynamically typed language) you can't
decide which version to take. So you have to decide on _one_, and as every
kid in school learns that (5+4) * 5 is 45, it was a reasonable decision to
use the semantics we have today.

No my opinion is not wrong, you just don't understand what I'm saying.

No it was not reasonable to introduce the semantics that made 2 * (1,2)
equal (1,2,1,2) IMO they should have used a differend operator for that
and not the *.
For someone who expresses his disliking to type _one_ comma in the few cases
of single element tuples in thousands of lines of code, it strikes me odd
that you'd go an are willing to add extra trouble entering _each_ and
_every_ tuple in your code by using some hitherto unknown character that
won't be enterable easily....

Where did I express this dislike. I'm not denying it because I know I
forget such things, but I sure don't remember now.
But you showed that strange sense of reasoning before - I remember you
wanting to shave off microseconds by optimising constant expressions like
5*4,

AFAIR I was just exploring ideas.
whilst at the same time arguing in another thread that you'd like to
have mutable keys for dicts that needed copying the very same keys - at
much greater costs, per case and even more so in general as using dicts is
common where pure constant arithmetic expressions aren't.

Well it seems you didn't follow that thread thorougly. If you had you
would have known that if the objects one had to work with were at
the same time mutable and usefull as keys, you have to turn them
into an immutable now for use as a key. This is a copy operation.
So compared to the situation now, no extra copying would be necessary
and no extra costs would be needed.
 
D

Diez B. Roggisch

So python choose a non-deterministic direction. To me (2,3) + (4,5)
equals (6,8). I don't dispute that having an operator to combine
(2,3) and (4,5) in (2,3,4,5) is usefull, but they should never have
used the "+" for that.

It certainly did not choose a nondeterministic action - that would mean that
it followed _both_ possibilities at the same time. Which clearly is not
happening.

And we didn't talk about (2,3) + (4,5) not being (6,8) - that's adding two
tuples, not having (9) beeing a tuple instead of a simple nine.

Of course one could have overloaded tuples that way - component wise
addition - but then people would want other kinds of vector algebraic stuff
working on them. But they are not vectors, they are tuples.

And in general, that is an entirely new discussion about the overloading of
operators for tuples, not the syntax of how to create them (which is
legitimate, of course - but misleading for this thread.)
No my opinion is not wrong, you just don't understand what I'm saying.

You alter the subject of discussion (see below), which caused that
confusion.
No it was not reasonable to introduce the semantics that made 2 * (1,2)
equal (1,2,1,2) IMO they should have used a differend operator for that
and not the *.

Maybe - but thats an alltogether different discussion, as I said before.

The point that made me kick into this discussion was:

"""
You really, really want (3 + 5) to be an integer, not a one-item tuple.

I sometimes do wonder if some impliciteness wouldn't be better here,
so that any item could be treated as if it was a one-item tuple.
"""

So you wanted (8) to be a tuple, or even more so 3 + 5 being (3,) + (5,).
What has that to do with the operator overloading of tuples in general?
It's a syntactic question we're discussing, _not_ a semantic one.

As I stated before, it could become a question of type semantics if python
was statically typed, as then the context of a expression like (8) could
determine which type has to be created - tuple of one item, or simple 8.
But it's not doable in python.
Where did I express this dislike. I'm not denying it because I know I
forget such things, but I sure don't remember now.

I showed the quote above - you wanted to have (8) behave as (8,) - so I
concluded you either don't like typing that extra comma, or alternatively
want introduce a new pair of parentheses to express tuples.
Well it seems you didn't follow that thread thorougly. If you had you
would have known that if the objects one had to work with were at
the same time mutable and usefull as keys, you have to turn them
into an immutable now for use as a key. This is a copy operation.
So compared to the situation now, no extra copying would be necessary
and no extra costs would be needed.

I did follow it, and I didn't say that the copying was necessary all the
time, even for immutable keys.
 
K

Kay Schluehr

Antoon said:
for instance I have written once somekind of vector class where
it was natural for these vectors to be added as well as te be
concatenated. Unfortunately python uses "+" for both so I had
no way to have both operators in a natural way in python.

Yes this is a quite common problem if one wants to have both an
addition- and a concatenation operator. I created once a <Hex> class
representing both a bytecode and a number and i resolved the need for
a concatenation by overloading __floordiv__. Both a __div__ and a
__floordiv__ are not needed for most of the types that are not ints.
0x7800

I would have prefered overloading a common concatenation operaor, say
__cat__ which is mapped onto "||" but i think using "+" for
concatenation comes from the convenience to concatenate strings in this
manner in other languages and has spreaded into the domain of lists and
tuples in Python.

On the other hand i find Mathematicas list operators very appealing:

In =: [1,2,3]^2
Out=: [1,4,9]

Compared with this suggar the list comprehension [x**2 for x in
[1,2,3]]
is ugly.

Regards Kay
 
A

Antoon Pardon

Op 2005-03-17 said:
It certainly did not choose a nondeterministic action - that would mean that
it followed _both_ possibilities at the same time. Which clearly is not
happening.
And we didn't talk about (2,3) + (4,5) not being (6,8) - that's adding two
tuples, not having (9) beeing a tuple instead of a simple nine.

We talked about the confusion that could arrise if a number could be
interpreted as a tuple because the '+' operator has a different
kind of result depending on whether the operands are numbers or
tuples. However if adding tuples would have been defined as
above their would have been a confusion because the result
would have been equivallent. 4 + 5 would have been 9 and
(4,) + (5,) would have been (9,)

And having chosen such a design wouldn't have made python
any less dynamic. So saying that the problem is the result
of python being dynamic as you once did is nonsense.
Of course one could have overloaded tuples that way - component wise
addition - but then people would want other kinds of vector algebraic stuff
working on them. But they are not vectors, they are tuples.

That could very well have been left to the users themselves. They
only needed to have used a different character for concatenation
instead of the "+".
And in general, that is an entirely new discussion about the overloading of
operators for tuples, not the syntax of how to create them (which is
legitimate, of course - but misleading for this thread.)

You claimed it was pythons dynamic nature that makes it difficult
to use items and one-item tuples as equivallent. I say
it has little to do with tha dynamic nature but more with the
design to use the same characters for sequence and number operations.
If these operations would have been indicated by different characters
no such problem would arrise with doing such unification.
You alter the subject of discussion (see below), which caused that
confusion.


Maybe - but thats an alltogether different discussion, as I said before.

No it is not. It is part of a counter argument to your claim
that python's dynamic nature is in the way.
The point that made me kick into this discussion was:

"""

I sometimes do wonder if some impliciteness wouldn't be better here,
so that any item could be treated as if it was a one-item tuple.
"""
So you wanted (8) to be a tuple, or even more so 3 + 5 being (3,) + (5,).
What has that to do with the operator overloading of tuples in general?
It's a syntactic question we're discussing, _not_ a semantic one.

I didn't say I want that. I was just wondering if unification between
numbers and one number tuples wouldn't have been a good solution with
the confusion people have about (1) not being a tuple.
As I stated before, it could become a question of type semantics if python
was statically typed, as then the context of a expression like (8) could
determine which type has to be created - tuple of one item, or simple 8.
But it's not doable in python.

It has litte to do with statically typing. But when I explain that
and show what will cause a problem with such unification in current
python you say I'm altering the subject.
I showed the quote above - you wanted to have (8) behave as (8,) - so I
concluded you either don't like typing that extra comma, or alternatively
want introduce a new pair of parentheses to express tuples.

I was wondering about the merrits of (8) behaving as (8,) that is
not the same as wanting it. May be you shouldn't read thing that
are not there.
 
A

Antoon Pardon

Op 2005-03-16 said:
Diez said:
I reread his example and have to admit I'm confused: He complains about
having written his _own_ vector class - and concatenation and addition had
to use both + ?

I've interpreted it as:
If Python had choosen different operators for addition and sequence
concatenation, I could have implemented them both in my vector class. As
it is, I have to implement one of them using a non-standard operator.
The examples focus too much on numbers - if we use instead

("foo")

we would get a iterable yielding ["foo",] or - as string already supports
iteration - ['f', 'o', 'o']. Which one to chose?

What I was hinting at (NOT proposing, I'd hate this) was that integers
implement the [] operator. 5 [0] would then return 5, for all practical
purposes, it would look like a tuple. String already implements []. Yes,
that would lead to really surprising and inconsistent behaviour.
Well, the number of operators built into the language is limited - and I
actually prefer to have the possibility to overload these if I want to.
Nobody forces me - I could use

v1.concat(v2)

for two vectors v1, v2 if I wanted to.

My peeve is about having operators added to standard types. This
increases the chances that using an object the wrong way leads to a
bogus result, not a runtime error. A more common programming error I
commit is passing a string where a list ist expected. And then I wonder
why later operations work on one-character strings.

The standard answer to this seems to be to use unittesting.
 
D

Daniel Dittmar

Antoon said:
The standard answer to this seems to be to use unittesting.

I do detect that there is a problem. It just takes longer to find the
source of bogus data than to look at a stack trace.

Daniel
 
A

Antoon Pardon

Op 2005-03-18 said:
I do detect that there is a problem. It just takes longer to find the
source of bogus data than to look at a stack trace.

Sure. But some language features would make finding the source of
some problems even faster. But when those arguments are made
the response is: use unittesting.
 
S

Steven Bethard

Kay said:
On the other hand i find Mathematicas list operators very appealing:

In =: [1,2,3]^2
Out=: [1,4,9]

Compared with this suggar the list comprehension [x**2 for x in
[1,2,3]]
is ugly.

py> import numarray
py> a = numarray.array([1, 2, 3])
py> a**2
array([1, 4, 9])

STeVe
 
C

Christos TZOTZIOY Georgiou

The big question is, is it the parens that make it a tuple, or is it
the comma? If you go along with the parens school of thought, then
(1,) is the special case. If you believe in commas, then the () is
the special case. In either case, it's a bit ugly, but we learn to
overlook the occasional cosmetic blemishes of those we love :)

My take on this is that comma defines tuples, and () is the exception.

..>> tpl = 1, 2, 3 * 4; print tpl
(1, 2, 12)
..>> tpl = (1, 2, 3) * 4; print tpl
(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)

So parentheses just change precedence (comma has lower precedence than
star).
 
J

Joal Heagney

Antoon Pardon wrote:
So python choose a non-deterministic direction. To me (2,3) + (4,5)
equals (6,8). I don't dispute that having an operator to combine
(2,3) and (4,5) in (2,3,4,5) is usefull, but they should never have
used the "+" for that.

("alph", "bravo") + ("delta", "max") --> ("alphdelta", "bravomax")

As we say in Australia, "What The ....."

Joal
 
A

Antoon Pardon

Op 2005-03-27 said:
Antoon Pardon wrote:


("alph", "bravo") + ("delta", "max") --> ("alphdelta", "bravomax")

No, that wouldn't be the result. You are still using "+" for
concatenation, even if only on strings. I say python should
have used something else for concatenation (string concatenation
included)
 
V

Ville Vainio

Antoon> No, that wouldn't be the result. You are still using "+"
Antoon> for concatenation, even if only on strings. I say python
Antoon> should have used something else for concatenation (string
Antoon> concatenation included)

To me, nothing is more natural than "ab" + "cd" == "abcd". Also [1,2]
+ [3,4] == [1,2,3,4]. "Dot product" is not really too useful in real
world (non-mathematical) apps.
 
V

Ville Vainio

Ville> To me, nothing is more natural than "ab" + "cd" ==
Ville> "abcd". Also [1,2] + [3,4] == [1,2,3,4]. "Dot product" is
Ville> not really too useful in real world (non-mathematical)
Ville> apps.

.... and of course by "dot product", I don't mean dot product at all. I
was thinking of summing vectors, which is not that much more common
either.
 
A

Antoon Pardon

Op 2005-03-29 said:
Antoon> No, that wouldn't be the result. You are still using "+"
Antoon> for concatenation, even if only on strings. I say python
Antoon> should have used something else for concatenation (string
Antoon> concatenation included)

To me, nothing is more natural than "ab" + "cd" == "abcd". Also [1,2]
+ [3,4] == [1,2,3,4]. "Dot product" is not really too useful in real
world (non-mathematical) apps.

What is more natural, that you concatenate strings and lists or that
you use the "+" for it. Suppose python would have used '#" to express
concatenation so that "ab" # "cd" == "abcd". After using this for
sometime nothing would have been more natural than this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top