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

Is behavior of += intentional for int?

1 view
Skip to first unread message

zaur

unread,
Aug 29, 2009, 8:45:54 AM8/29/09
to
Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> a=1
>>> x=[a]
>>> id(a)==id(x[0])
True
>>> a+=1
>>> a
2
>>> x[0]
1

I thought that += should only change the value of the int object. But
+= create new.
Is this intentional?

Paul McGuire

unread,
Aug 29, 2009, 9:08:49 AM8/29/09
to

ints are immutable. But your logic works fine with a mutable object,
like a list:

>>> a = [1]
>>> x = [a]
>>> print id(a) == id(x[0])
True
>>> a += [1]
>>> print a
[1, 1]
>>> print x[0]
[1, 1]

What exactly are you trying to do?

-- Paul

Günther Dietrich

unread,
Aug 29, 2009, 9:23:20 AM8/29/09
to
zaur <szp...@gmail.com> wrote:

An integer variable contains the reference (ID) to an (immutable)
integer object; it doesn't contain the value itself. So, when you assign
a new value to an integer variable, it will contain the reference to the
object containing the new value, afterwards.

If you assign an integer variable to a list element, this reference will
be written into the list. The assignment of a new value to the integer
variable will create a new integer object, containing the new value, and
put the reference to it into the integer variable.
The reference to the object with the old value, that is stored in the
list, won't be touched.


In fact, it is a result of integers in python being immutable.

Best regards,

Günther

Günther Dietrich

unread,
Aug 29, 2009, 12:25:54 PM8/29/09
to
Paul McGuire <pt...@austin.rr.com> wrote:

>What exactly are you trying to do?

I think, he wants to kind of dereference the list element. So that he
can write

>>> a += 1

instead of

>>> long_name_of_a_list_which_contains_data[mnemonic_pointer_name] += 1

Regards,

Günther

zaur

unread,
Aug 29, 2009, 2:11:43 PM8/29/09
to

That's right. I thought that int as object will stay the same object
after += but with another integer value.
My intuition said me that int object which represent integer value
should behave this way.
But by design python's integer behave differently.

I fond that NumPy's 1-d types behaves as objects with mutable values.

>>> from numpy import *

>>> a=array([1])
>>> id(a)
10912544
>>> a += 1
>>> id(a)
10912544
>>> a
array([2])

Steven D'Aprano

unread,
Aug 29, 2009, 3:03:23 PM8/29/09
to
On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:

> I thought that int as object will stay the same object after += but with
> another integer value. My intuition said me that int object which
> represent integer value should behave this way.

If it did, then you would have this behaviour:


>>> n = 3 # bind the name n to the object 3
>>> saved_id = id(n) # get the id of the object
>>> n += 1 # add one to the object 3
>>> assert n == 4 # confirm that it has value four
>>> assert id(n) == saved_id # confirm that it is the same object
>>> m = 3 # bind the name m to the object 3
>>> print m + 1 # but object 3 has been modified
5

This would be pretty disturbing behaviour, and anything but intuitive.

Fortunately, Python avoids this behaviour by making ints immutable. You
can't change the object 3 to have any other value, it will always have
value three, and consequently n+=1 assigns a new object to n.


--
Steven

AggieDan04

unread,
Aug 29, 2009, 4:25:35 PM8/29/09
to
On Aug 29, 8:08 am, Paul McGuire <pt...@austin.rr.com> wrote:
> On Aug 29, 7:45 am, zaur <szp...@gmail.com> wrote:
>
> > Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
> > [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
> > Type "copyright", "credits" or "license()" for more information.>>> a=1
> > >>> x=[a]
> > >>> id(a)==id(x[0])
> > True
> > >>> a+=1
> > >>> a
> > 2
> > >>> x[0]
>
> > 1
>
> > I thought that += should only change the value of the int object. But
> > += create new.
> > Is this intentional?
>
> ints are immutable.  But your logic works fine with a mutable object,
> like a list:

Technically, mutability isn't the issue: There's nothing enforcing
that a mutable object HAS to have an __iadd__ method that returns the
same object.

Derek Martin

unread,
Aug 30, 2009, 3:33:05 AM8/30/09
to Steven D'Aprano, pytho...@python.org
On Sat, Aug 29, 2009 at 07:03:23PM +0000, Steven D'Aprano wrote:
> On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
>
> > I thought that int as object will stay the same object after += but with
> > another integer value. My intuition said me that int object which
> > represent integer value should behave this way.
>
> If it did, then you would have this behaviour:

No, you wouldn't; the behavior you described is completely different
from, and incompatible with, what zaur wrote.

He's saying that instead of thinking the integer value of 3 itself
being the object, he expected Python's object model would behave as
though the entity m is the object, and that object exists to contain
an integer value. In that case, m is always m, but it has whatever
integer value it is told to hold at any point in time. The
self-referential addition would access the value of m, add the
operand, and store the result back in the same object as the object's
value. This is not the way Python works, but he's saying this is the
intuitive behavior. I happen to agree, and argued at length with you
and others about that very thing months ago, when some other third
party posted with that exact same confusion.

By contrast, your description maintains the concept of numerical value
as object that Python uses, and completely misses the point. I did
find the description you gave to be highly enlightening though... It
highlighted perfectly, I think, exactly why it is that Python's behavior
regarding numerical values as objects is *not* intuitive. Of course,
intuition is highly subjective.

I believe it boils down to this: People expect that objects they
create are mutable. At least, unless they specify otherwise. It is
so in some other programming languages which people may be likely to
be familiar with (if they are not taking their first forray into the
world of computing by learning Python), and even "real world" objects
are essentially always mutable. If you have a 2002 Buick LeSabre, it
has a number of attributes, including its length, which might be 8.5
feet, for instance. However, this is not fixed: by adding modified
body parts, or as an extreme example by sawing off the trunk of the
car, the length and indeed the object itself has been changed.
However, despite having been modified, it is at least in some sense
still the same object: it is still a 2002 Buick LeSabre, and it still
has the same *identity* (the same VIN number). It's the same object,
but its value(s) changed. [Not that it matters, but I do not own such
a car. :)]

Numbers are fundamentally different from objects. The number 3 is a
symbol of the idea of the existence of three countable objects. It
can not be changed (though it can be renamed, if you so choose -- just
don't expect most people to know what you're talking about). It is
unintuitive that 3 is an object; it is rather what we use to describe
objects -- the value of the object. It is an abstract concept, and
as such it is not an object at all. You cannot hear 3, taste
3, nor smell 3. You can neither see nor touch 3, though you can
certainly see 3 *objects* if they are present, and you can certainly
see the symbol '3' that we use to represent that idea... but you can
not see three itself, because there is no such object. The only way
to see three is to envision 3 of some object. The number 3 does not
have a value; it IS a value (it is the symbolic representation of the
value of three). To say that 3 is an object that has a value is a bit
like saying the length of a car is an object that itself has a length.
It just doesn't compute.

THAT is why Python's behavior with regard to numerical objects is
not intuitive, and frankly bizzare to me, and I dare say to others who
find it so.

Yes, that's right. BIZZARE.

Of course, none of this is real. In the end, it's all just a bunch of
wires that either have current or don't. It's only how *WE* organize
and think about that current that gives it any meaning. So you're
free to think about it any way you like.

--
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D

Mark Dickinson

unread,
Aug 30, 2009, 4:01:37 AM8/30/09
to
On Aug 29, 8:03 pm, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.au> wrote:
> On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
> > I thought that int as object will stay the same object after += but with
> > another integer value. My intuition said me that int object which
> > represent integer value should behave this way.
>
> If it did, then you would have this behaviour:
>
> >>> n = 3                     # bind the name n to the object 3
> >>> saved_id = id(n)          # get the id of the object
> >>> n += 1                    # add one to the object 3
> >>> assert n == 4             # confirm that it has value four
> >>> assert id(n) == saved_id  # confirm that it is the same object
> >>> m = 3                     # bind the name m to the object 3
> >>> print m + 1               # but object 3 has been modified
>
> 5

I don't see how that follows. In an alternative interpretation, the
int literals would all be thought of as distinct objects: that is,
the line 'n = 3' creates an integer object with value 3 and binds the
name n to it; the later line 'm = 3' then creates another *new*
integer object with value 3 and binds the name m to it. In other
words, it could work in exactly the same way as the following works in
Python:

>>> n = {}
>>> n[1729] = 10585
>>> m = {}
>>> m
{}

The modification to n doesn't affect m, since the two occurrences of
{} give distinct dictionary objects.

--
Mark

Steven D'Aprano

unread,
Aug 30, 2009, 6:34:17 AM8/30/09
to
On Sun, 30 Aug 2009 02:33:05 -0500, Derek Martin wrote:

> On Sat, Aug 29, 2009 at 07:03:23PM +0000, Steven D'Aprano wrote:
>> On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
>>
>> > I thought that int as object will stay the same object after += but
>> > with another integer value. My intuition said me that int object
>> > which represent integer value should behave this way.
>>
>> If it did, then you would have this behaviour:
>
> No, you wouldn't; the behavior you described is completely different
> from, and incompatible with, what zaur wrote.
>
> He's saying that instead of thinking the integer value of 3 itself being
> the object, he expected Python's object model would behave as though the
> entity m is the object, and that object exists to contain an integer
> value.

What is "the entity m"?

Is it the name m, as follows?

>>> m = 3 # bind the object 3 to the name m

Or is it the literal "3" (without quotes)?

Or an object holding the value three?

Or something else?


> In that case, m is always m,
> but it has whatever integer value
> it is told to hold at any point in time. The self-referential addition
> would access the value of m, add the operand, and store the result back
> in the same object as the object's value.

Ah wait, I think I get it... is m a memory location? So when you say:

m = 3

the memory location that m represents is set to the value 3, and when you
say:

m += 1

the memory location that m represents is set to the value 4?

That would be how Pascal and C (and presumably other languages) work, but
not Python or Ruby or even VB (so I'm told) and similar languages. Java
has a hybrid model, where a few data types (such as ints) are handled
like C, and everything else is handled like Python. Consistency was never
Java's strong suit.


> This is not the way Python
> works, but he's saying this is the intuitive behavior.

It isn't intuitive if you've never been exposed to Pascal- or C-like
languages. If your only programming language was Haskell, the very idea
of mutating values would be alien. So I guess when you say "the intuitive
behaviour", what you actually mean is "familiar".


> I happen to
> agree, and argued at length with you and others about that very thing
> months ago, when some other third party posted with that exact same
> confusion.
>
> By contrast, your description maintains the concept of numerical value
> as object that Python uses, and completely misses the point. I did find
> the description you gave to be highly enlightening though... It
> highlighted perfectly, I think, exactly why it is that Python's behavior
> regarding numerical values as objects is *not* intuitive. Of course,
> intuition is highly subjective.

What exactly is it about Python's behaviour regarding numbers that is not
intuitive? That you can't do this?

>>> anum = 2
>>> alist = [anum]
>>> anum += 1
>>> print alist # this doesn't work
[3]

That won't work in any language that I know of -- as far as I am aware,
the above is impossible in just about every common programming language.
(My C and VB are nearly non-existent, so I may be wrong about them.) Here
is Ruby's behaviour:

irb(main):001:0> anum = 2
=> 2
irb(main):002:0> alist = [anum]
=> [2]
irb(main):003:0> anum += 1
=> 3
irb(main):004:0> puts alist
2
=> nil


Just like Python.


> I believe it boils down to this: People expect that objects they create
> are mutable.

Why would they expect that? Is there any evidence apart from the
anecdotal complaints of a few people that they expect this? People
complain equally when they use a mutable default value and it mutates, or
that they can't use mutable objects as dict keys, so this suggests that
people expect objects should be immutable and are surprised when they
change.

If you're going to argue by analogy with the real world (as you do
further on), I think it's fair to argue that some objects are mutable
(pieces of rubber that expand into a balloon when you blow into them),
and some are immutable unless you expend extraordinary effort (rocks). I
would be gobsmacked if my desk turned pink or changed into an armchair, I
expect it to be essentially unchanging and immutable. But I fully expect
a banana to turn black, then squishy, and finally white and fuzzy if I
leave it long enough.


> At least, unless they specify otherwise. It is so in some
> other programming languages which people may be likely to be familiar
> with (if they are not taking their first forray into the world of
> computing by learning Python), and even "real world" objects are
> essentially always mutable.

[snip example of a 2002 Buick LeSabre]

Be careful bringing real-world examples into this. People have been
arguing about identity in the real-world for millennia. See, for example,
the paradox of my great-grandfather's axe. My great-grandfather's axe is
still in my family after 80 years, as good as new, although the handle
has been replaced four times and the head twice. But it's still the same
axe. An even older example is the paradox of the Ship of Theseus.


> Numbers are fundamentally different from objects. The number 3 is a
> symbol of the idea of the existence of three countable objects. It can
> not be changed

Doesn't this contradict your claim that people expect to be able to
mutate numbers? That you should be able to do this?

>>> x = 3
>>> id(x)
123456
>>> x += 1
>>> assert x == 4
>>> id(x)
123456


You can't have it both ways -- if people think of objects as mutable, and
think of numbers as not-objects and unchanging, then why oh why would
they find Python's numeric behaviour to be unintuitive?


> (though it can be renamed, if you so choose -- just don't
> expect most people to know what you're talking about). It is
> unintuitive that 3 is an object;

Says you. People have considered numbers to be eternal, unchanging,
immutable entities going back to at least Plato. If people are
comfortable thinking that there are Platonic ideal numbers, why wouldn't
they think of them represented in computers as immutable objects?

What I think is that some people, such as you and Zaur, have *learned*
from C-like languages that numbers are mutable not-objects, and you've
learned it so well that you've forgotten that you ever needed to learn
it. Consequently what you actually mean when you say Python is
unintuitive is that Python is not like some other language (and is like
yet other languages).


> it is rather what we use to describe
> objects -- the value of the object. It is an abstract concept, and as
> such it is not an object at all. You cannot hear 3, taste 3, nor smell
> 3. You can neither see nor touch 3, though you can certainly see 3
> *objects* if they are present, and you can certainly see the symbol '3'
> that we use to represent that idea... but you can not see three itself,
> because there is no such object.

Human beings are excellent at reifying abstract things into (imaginary)
objects. We talk about letting in the cold (we actually let out the
heat); we talk about souls and life-force as if they are things; we treat
justice and love and mercy and hate as palpable things instead of
emotions and abstract entities. Plato imagined that everything has a
pure, abstract form, an ideal, and people find that intuitive: we expect
that there is an archetypal "chair" that embodies everything that is
chair-like and nothing which is not, if only we could find it.

Numbers are no different. Reifying them into objects comes easy to people
who haven't learned differently.


> The only way to see three is to
> envision 3 of some object. The number 3 does not have a value; it IS a
> value (it is the symbolic representation of the value of three). To say
> that 3 is an object that has a value is a bit like saying the length of
> a car is an object that itself has a length.

No, the length of a car is an object which *is* a length, it doesn't
*have* a length.


> It just doesn't compute.

None of this explains why you would expect to be able to mutate the value
three and turn it into four.

I don't think your argument makes sense -- I think your explanation is
tangled up in knots. Everything you say about numbers being unchangeable,
immutable entities supports Python's behaviour to make numbers immutable,
and yet you argue that since people expect numbers to be unchanging, they
therefore expect Python ints to be mutable! This makes no sense.


> THAT is why Python's behavior with regard to numerical objects is not
> intuitive, and frankly bizzare to me, and I dare say to others who find
> it so.
>
> Yes, that's right. BIZZARE.

I think you have confused yourself. If the number three cannot change,
and you have a label "m" associated with three, then if you add one to
it, you *can't* have the three mutate into a four, because numbers cannot
change. Obviously the label has to detach itself off the three and onto
the four -- precisely the behaviour Python uses. Plato would surely have
found this commonsensical, and I would say that it's only those who have
become used to Pascal-like languages that don't.


--
Steven

Paul McGuire

unread,
Aug 30, 2009, 6:42:06 AM8/30/09
to
On Aug 30, 2:33 am, Derek Martin <c...@pizzashack.org> wrote:
> THAT is why Python's behavior with regard to numerical objects is
> not intuitive, and frankly bizzare to me, and I dare say to others who
> find it so.
>
> Yes, that's right.  BIZZARE.
>

Can't we all just get along?

I think the question boils down to "where is the object?". In this
statement:

a = 3

which is the object, a or 3?

There exist languages (such as C++) that allow you to override the '='
assignment as a class operator. So that I could create a class where
I decided that assigning an integer value to it applies some
application logic, probably the setting of some fundamental
attribute. In that language, 'a' is the object, and 3 is a value
being assigned to it. This can cause some consternation when a reader
(or worse, maintainer) isn't familiar with my code, sees this simple
assignment, and figures that they can use 'a' elsewhere as a simple
integer, with some surprising or disturbing results.

Python just doesn't work that way.

Python binds values to names. Always. In Python, "=" is not and never
could be a class operator. In Python, any expression of LHS = RHS,
LHS is always a name, and in this statement it is being bound to some
object found by evaluating the right hand side, RHS.

The bit of confusion here is that the in-place operators like +=, -=,
etc. are something of a misnomer - obviously a *name* can't be
incremented or decremented (unlike a pointer in C or C++). One has to
see that these are really shortcuts for LHS = LHS + RHS, and once
again, our LHS is just a name getting bound to the result of LHS +
RHS. Is this confusing, or non-intuitive? Maybe. Do you want to write
code in Python? Get used to it. It is surprising how many times we
think things are "intuitive" when we really mean they are "familiar".
For long-time C and Java developers, it is intuitive that variables
are memory locations, and switching to Python's name model for them is
non-intuitive.

As for your quibble about "3 is not an object", I'm afraid that may be
your own personal set of blinders. Integer constants as objects is
not unique to Python, you can see it in other languages - Smalltalk
and Ruby are two that I know personally. Ruby implements a loop using
this interesting notation:

3.times do
...do something...
end

Of course, it is a core idiom of the language, and if I adopted Ruby,
I would adopt its idioms and object model.

Is it any odder that 3 is an object than that the string literal
"Hello, World!" is an object? Perhaps we are just not reminded of it
so often, because Python's int class defines no methods that are not
"__" special methods (type in "dir(3)" at the Python prompt). So we
never see any Python code referencing a numeric literal and
immediately calling a method on it, as in Ruby's simple loop
construct. But we do see methods implemented on str like split(), and
so "about above across after against".split() gives me a list of the
English prepositions that begin with "a". We see this kind of thing
often enough, we get accustomed to the objectness of string literals.
It gets to be so familiar, it eventually seems "intuitive". You
yourself mentioned that intuition is subjective - unfortunately, the
"intuitiveness" of a feature is often tied to its value as a coding
concept, and so statements of non-intuitiveness can be interpreted as
a slant against the virtue of that concept, or even against the
language itself.

Once we accept that 3 is an object, we clearly have to stipulate that
there can be no changes allowed to it. 3 must *always* have the value
of the integer between 2 and 4. So our language invokes the concept
that some classes create instances that are immutable.

For a Python long-timer like Mr. D'Aprano, I don't think he even
consciously thinks about this kind of thing any more; his intuition
has aligned with the Python stars, so he extrapolates from the OP's
suggestion to the resulting aberrant behavior, as he posted it.

You can dispute and rail at this core language concept if you like,
but I think the more entrenched you become in the position that "'3 is
an object' is bizarre", the less enjoyable your Python work will be.

-- Paul

Steven D'Aprano

unread,
Aug 30, 2009, 6:44:48 AM8/30/09
to
On Sun, 30 Aug 2009 01:01:37 -0700, Mark Dickinson wrote:

> On Aug 29, 8:03 pm, Steven D'Aprano <st...@REMOVE-THIS-
> cybersource.com.au> wrote:
>> On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
>> > I thought that int as object will stay the same object after += but
>> > with another integer value. My intuition said me that int object
>> > which represent integer value should behave this way.
>>
>> If it did, then you would have this behaviour:
>>
>> >>> n = 3                     # bind the name n to the object 3
>> >>> saved_id = id(n)          # get the id of the object n += 1        
>> >>>            # add one to the object 3 assert n == 4             #
>> >>> confirm that it has value four assert id(n) == saved_id  # confirm
>> >>> that it is the same object m = 3                     # bind the
>> >>> name m to the object 3 print m + 1               # but object 3 has
>> >>> been modified
>>
>> 5
>
> I don't see how that follows.

Okay, it follows given Python's caching of small integer objects.

It also follows from the idea that there is one abstract entity which
English speakers call "three" and write as 3. There's not two identical
entities with value 3, or four, or a million of them, only one.

But of course your alternative implementation (where every time the
Python VM sees the literal 3 it creates a new integer object with that
value) would also be a valid, albeit inefficient, implementation. To be
honest, I didn't even think of that.


--
Steven

Paul McGuire

unread,
Aug 30, 2009, 6:52:36 AM8/30/09
to
On Aug 30, 5:42 am, Paul McGuire <pt...@austin.rr.com> wrote:
> Python binds values to names. Always. In Python, "=" is not and never
> could be a class operator.  In Python, any expression of LHS = RHS,
> LHS is always a name, and in this statement it is being bound to some
> object found by evaluating the right hand side, RHS.
>
An interesting side note, and one that could be granted to the OP, is
that Python *does* support the definition of class operator overrides
for in-place assignment operators like += (by defining a method
__iadd__). This is how numpy's values accomplish their mutability.

> It is surprising how many times we
> think things are "intuitive" when we really mean they are "familiar".

Of course, just as I was typing my response, Steve D'Aprano beat me to
the punch.

Maybe it's time we added a new acronym to this group's ongoing
discussions: PDWTW, or "Python doesn't work that way".

-- Paul

Albert Hopkins

unread,
Aug 30, 2009, 7:09:46 AM8/30/09
to pytho...@python.org
On Sun, 2009-08-30 at 10:44 +0000, Steven D'Aprano wrote:
> It also follows from the idea that there is one abstract entity which
> English speakers call "three" and write as 3. There's not two
> identical
> entities with value 3, or four, or a million of them, only one.

That's not true. There are many different 3s in all the parallel
universes. ;)

-a

Carl Banks

unread,
Aug 30, 2009, 7:26:54 AM8/30/09
to
On Aug 30, 12:33 am, Derek Martin <c...@pizzashack.org> wrote:
[snip rant]

> THAT is why Python's behavior with regard to numerical objects is
> not intuitive, and frankly bizzare to me, and I dare say to others who
> find it so.
>
> Yes, that's right.  BIZZARE.

You mean it's different from how you first learned it.


Carl Banks

Carl Banks

unread,
Aug 30, 2009, 7:49:51 AM8/30/09
to
On Aug 30, 3:34 am, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.au> wrote:
> On Sun, 30 Aug 2009 02:33:05 -0500, Derek Martin wrote:
> > On Sat, Aug 29, 2009 at 07:03:23PM +0000, Steven D'Aprano wrote:
> >> On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
>
> >> > I thought that int as object will stay the same object after += but
> >> > with another integer value. My intuition said me that int object
> >> > which represent integer value should behave this way.
>
> >> If it did, then you would have this behaviour:
>
> > No, you wouldn't; the behavior you described is completely different
> > from, and incompatible with, what zaur wrote.
>
> > He's saying that instead of thinking the integer value of 3 itself being
> > the object, he expected Python's object model would behave as though the
> > entity m is the object, and that object exists to contain an integer
> > value.
>
> What is "the entity m"?

I think they (Derek and zaur) expect integer objects to be mutable.

It's pretty common for people coming from "name is a location in
memory" languages to have this conception of integers as an
intermediate stage of learning Python's object system. Even once
they've understood "everything is an object" and "names are references
to objects" they won't have learned all the nuances of the system, and
might still (not unreasonably) think integer objects could be mutable.

However, it'd be nice if all these people didn't post here whining
about how surprising and unintuitive it is and instead just said, "ah,
integers are immutable, got it", quietly to themselves.


Carl Banks

zaur

unread,
Aug 30, 2009, 9:32:22 AM8/30/09
to
On 29 авг, 23:03, Steven D'Aprano <st...@REMOVE-THIS-

This behavior is because small integers are cached internally. See

Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin

Type "help", "copyright", "credits" or "license" for more information.
>>> a=1
>>> c=1
>>> d=10000
>>> e=10000
>>> id(a),id(c),id(d),id(e)
(16793992, 16793992, 17067336, 17067276)

Albert Hopkins

unread,
Aug 30, 2009, 10:12:26 AM8/30/09
to pytho...@python.org
On Sun, 2009-08-30 at 04:49 -0700, Carl Banks wrote:
> It's pretty common for people coming from "name is a location in
> memory" languages to have this conception of integers as an
> intermediate stage of learning Python's object system. Even once
> they've understood "everything is an object" and "names are references
> to objects" they won't have learned all the nuances of the system, and
> might still (not unreasonably) think integer objects could be mutable.
>
I agree. Python (and other similar languages?) are different in that.
'x' does not point to an area in memory, where you can do anything with
that area. But in Python there are objects, and they are "references"
in memory that some magical "reference counter" keeps track of for us
(and that's a wonderful thing). And what is 'x'? Well 'x' is just some
"label" that just so happens to have the privelage of being associated
with this "unnamed" object. 'x' could just as easily associate itself
with another object.

I think that the Blue programming language, which I have been looking at
lately, makes this distinction even clearer. For example, functions are
not defined by names at all. Instead of

def funcname(): ...

You have

func{...};

If you actually want to be able to reference the function later (as you
probably would) then it's just a simple assignment just like any other
assignment:

funcname = func{...};

But i think it makes it more clear that "funcname" just so happens to
reference this object that's a function. It's the same basic philosophy
when applied to methods:

MyClass = sys.class();
MyClass.my_method = func{...};

Blue also has interesting, simple rules wrt scopes. It's a surprisingly
small, simple language (yet in a very early stage of development.

> However, it'd be nice if all these people didn't post here whining
> about how surprising and unintuitive it is and instead just said, "ah,
> integers are immutable, got it", quietly to themselves.

Yes, when I was first learning Python, at least the book I used made it
very clear when introducing a new type to specify that type as mutable
or immutable. It's a very core concept to Python. If you choose to
ignore it or refuse to understand it then you are asking for trouble.

-a


zaur

unread,
Aug 30, 2009, 12:37:49 PM8/30/09
to
On 30 авг, 15:49, Carl Banks <pavlovevide...@gmail.com> wrote:
> I think they (Derek and zaur) expect integer objects to be mutable.
>
> It's pretty common for people coming from "name is a location in
> memory" languages to have this conception of integers as an
> intermediate stage of learning Python's object system.  Even once
> they've understood "everything is an object" and "names are references
> to objects" they won't have learned all the nuances of the system, and
> might still (not unreasonably) think integer objects could be mutable.
>
> However, it'd be nice if all these people didn't post here whining
> about how surprising and unintuitive it is and instead just said, "ah,
> integers are immutable, got it", quietly to themselves.
>
> Carl Banks

Very expressive.

I use python many years. And many years I just took python int as they
are.
I am also not think about names as reference to objects and so on.

So this isn't the case.

Derek Martin

unread,
Aug 30, 2009, 12:40:51 PM8/30/09
to Steven D'Aprano, pytho...@python.org
On Sun, Aug 30, 2009 at 10:34:17AM +0000, Steven D'Aprano wrote:
> > He's saying that instead of thinking the integer value of 3 itself being
> > the object, he expected Python's object model would behave as though the
> > entity m is the object, and that object exists to contain an integer
> > value.
> What is "the entity m"?

The entity m is an object. Objects, in computer science, are
abstractions created by humans to make solving a large class of
problems easier to think about. An object is a piece of data, upon
which you can perform programmatic actions, which are grouped together
with the values contained in that data. It's an abstraction which
translates, in the physical sense, to a group of memory locations with
a reference in a symbol table.

> Ah wait, I think I get it... is m a memory location?

No, it isn't. It is an abstraction in the programmer's mind that sits
on top of some memory. For that matter, the memory location is
itself an abstraction. It is not a memory location, but a particular
series of circuits which either have current or don't. It is simply
convenient for us to think of it as a memory location.

> That would be how Pascal and C (and presumably other languages)
> work, but not Python or Ruby or even VB (so I'm told) and similar
> languages.

Well, except that, in fact, they do work that way. They simply
present a different abstraction to the programmer than C or other
languages. They have to work that way, at the lowest level, because
that is how the hardware works.

> > Numbers are fundamentally different from objects. The number 3 is a
> > symbol of the idea of the existence of three countable objects. It can
> > not be changed
>
> Doesn't this contradict your claim that people expect to be able to
> mutate numbers? That you should be able to do this?

This is where you continually fail. There is no contradiction at all.
What I'm saying is that in my view, numbers CAN'T mutate; they are not
objects! They are values, which are a means of describing objects.
Only the objects which hold the values can mutate. However in Python
they don't, and can't, but they EASILY could with a different design.
You, however, seem to be completely stuck on Python's behavior with
regard to numeric objects, and fail to see past that. Python's model
is only one abstraction, among multiple possibilities.

> You can't have it both ways -- if people think of objects as
> mutable, and think of numbers as not-objects and unchanging, then
> why oh why would they find Python's numeric behaviour to be
> unintuitive?

Because in Python, they ARE objects, which they think should be
mutable, but in Python when they try to change the *value* of the
object, they don't get the same object with a different value; they
get a completely different object. This is counter to their
experience. If you don't like the Buick example, then use algebra.
We've been down this road before, so I'm probably wasting my time...
In algebra, you don't assign a name to a value, you assign a value to
a variable. You can, in a different problem, assign a different value
to that variable, but the variable didn't change; only its value did.
In Python, it's the opposite.

> What I think is that some people, such as you and Zaur, have *learned*
> from C-like languages that numbers are mutable not-objects, and you've
> learned it so well that you've forgotten that you ever needed to learn
> it.

No, this is precisely why I provided the real-world examples -- to
illustrate to you that there was no need to learn it in computer
science, because the concept applies in the real world quite
intuitively in every-day situations. I think rather it is YOU who
have learned the concept in Python, and since then fail to imagine any
other possible interpretation of an object, and somehow have
completely forgotten the examples you encountered before Python, from
algebra and from the real world.

> Human beings are excellent at reifying abstract things into (imaginary)
> objects.

I don't know what the word "reifying" means, but irrelevant. Such
things are abstract, and in fact not objects.

> No, the length of a car is an object which *is* a length, it doesn't
> *have* a length.

It is not an object. It is an abstract idea used as a description of
an object.

> None of this explains why you would expect to be able to mutate the
> value three and turn it into four.

Again, you fail. I *DO NOT* expect that. I expect to be able to
mutate the object m, changing its value from 3 to 4.

> I think you have confused yourself.

No Steven, on this topic, it is only you who have been confused,
perpetually. Although, it could be said that Python's idea of what an
object is also is itself confused... Python (or at least the docs)
actually refrains from formally defining an object. The docs only say
that an object has an identity, a name, and a value. Well, OK... so 3
is an object. You can bind a name to it... except that's not exactly
correct. You can bind many names to it, and every time you write
something like:

m = 3

You are binding another name to the same object. That's intuitive?
So you say. But what is the value of 3? Is it 3? How can the value
of an object be the object itself? If that were true, then the value
of the object is an object, which has a value... you have an infinite
recursion. It's a paradox. How could you get any more unintuitive
than that?!

In practice it's not a paradox, because the values inside numeric
objects are *not* objects. They're numerical constants, as used by
the hardware (excepting that they are just an abstraction on top of
current, as noted before). Python's model breaks down at that point;
it is not so with most other types of objects... their values remain
objects. And *that* is inconsistent. The same is true of character
data as for numeric data. And that, I believe, is why Java treats
these as atomic data types, rather than as objects. Because they are,
in fact. They are types of data that the hardware knows how to deal
with, directly. Everything else is not.

Rhodri James

unread,
Aug 30, 2009, 12:57:23 PM8/30/09
to pytho...@python.org

Then you are doomed to surprises such as this.

--
Rhodri James *-* Wildebeest Herder to the Masses

Derek Martin

unread,
Aug 30, 2009, 1:04:45 PM8/30/09
to Paul McGuire, pytho...@python.org
On Sun, Aug 30, 2009 at 03:42:06AM -0700, Paul McGuire wrote:
> Python binds values to names. Always.

No, actually, it doesn't. It binds *objects* to names. This
distinction is subtle, but important, as it is the crux of why this is
confusing to people. If Python is to say that objects have values,
then the object can not *be* the value that it has, because that is a
paradoxical self-reference. It's an object, not a value.

> Is it any odder that 3 is an object than that the string literal
> "Hello, World!" is an object?

Yes. Because 3 is a fundamental bit of data that the hardware knows
how to deal with, requiring no higher level abstractions for the
programmer to use it (though certainly, a programming language can
provide them, if it is convenient). "Hello, World!" is not. They are
fundamentally different in that way.

> For a Python long-timer like Mr. D'Aprano, I don't think he even
> consciously thinks about this kind of thing any more; his intuition
> has aligned with the Python stars, so he extrapolates from the OP's
> suggestion to the resulting aberrant behavior, as he posted it.

I'm sure that's the case. But it's been explained to him before, and
yet he still can't seem to comprehend that not everyone immediately
gets this behavior, and that this is not without good reason.

So, since it *has* been explained to him before, it's somewhat
astonishing that he would reply to zaur's post, saying that the
behavior zaur described would necessarily lead to the insane behavior
that Steven described. When he makes such statements, it's tantamount
to calling the OP an idiot. I find that offensive, especially
considering that Steven's post displayed an overwhelming lack of
understanding of what the OP was trying to say.

> You can dispute and rail at this core language concept if you like,
> but I think the more entrenched you become in the position that "'3 is
> an object' is bizarre", the less enjoyable your Python work will be.

While I did genuinely find the behavior bizarre when I encountered it,
and honestly still do, I learned it quickly and moved past it. I'm
not suggesting that it be changed, and I don't feel particularly
strongly that it even should change. It's not so much the language
I'm railing against, but the humans...

Derek Martin

unread,
Aug 30, 2009, 1:27:57 PM8/30/09
to Paul McGuire, pytho...@python.org
On Sun, Aug 30, 2009 at 03:52:36AM -0700, Paul McGuire wrote:
> > It is surprising how many times we
> > think things are "intuitive" when we really mean they are "familiar".
>
> Of course, just as I was typing my response, Steve D'Aprano beat me to
> the punch.

Intuition means "The power or faculty of attaining to direct knowledge
or cognition without evident rational thought and inference." Very
naturally, things which behave in a familiar manner are intuitive.
Familiar and intuitive are very closely tied. Correspondingly, when
things look like something familiar, but behave differently, they are
naturally unintuitive.

Derek Martin

unread,
Aug 30, 2009, 1:36:17 PM8/30/09
to Carl Banks, pytho...@python.org
On Sun, Aug 30, 2009 at 04:26:54AM -0700, Carl Banks wrote:
> On Aug 30, 12:33 am, Derek Martin <c...@pizzashack.org> wrote:
> [snip rant]

I was not ranting. I was explaining a perspective.

> > THAT is why Python's behavior with regard to numerical objects is
> > not intuitive, and frankly bizzare to me, and I dare say to others who
> > find it so.
> >
> > Yes, that's right.  BIZZARE.
>
> You mean it's different from how you first learned it.

I mean exactly that I find it "strikingly out of the ordinary; odd,
extravagant, or eccentric in style or mode" as Webster's defines the
word. Whether it is so because it is different from how I first
learned it, or for some other reason, it is so nonetheless. I have
elsewhere gone into great detail about why I find it so. If you need
it to be simple, then feel free to simplify it.

OKB (not okblacke)

unread,
Aug 30, 2009, 1:43:42 PM8/30/09
to
Derek Martin wrote:

> If Python is to say that objects have values,
> then the object can not *be* the value that it has, because that is a
> paradoxical self-reference. It's an object, not a value.

But does it say that objects have values? I don't see where you
get this idea. Consider this code:

class A(object):
pass

class B(object):
x = 0

a = A()
b = B()
b2 = B()
b2.x = a

What is the "value" of the object now bound to the name "a"? What
about the "value" of the object bound to b, or b2?

I would say that in Python, objects do not have values. Objects
are values.

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown

Derek Martin

unread,
Aug 30, 2009, 2:21:09 PM8/30/09
to OKB (not okblacke), pytho...@python.org
On Sun, Aug 30, 2009 at 05:43:42PM +0000, OKB (not okblacke) wrote:
> Derek Martin wrote:
>
> > If Python is to say that objects have values,
> > then the object can not *be* the value that it has, because that is a
> > paradoxical self-reference. It's an object, not a value.
>
> But does it say that objects have values? I don't see where you
> get this idea.

Yes, it does say that. Read the docs. :)

http://docs.python.org/reference/datamodel.html

(paragraph 2)


> class A(object):
> pass

> a = A()


>
> What is the "value" of the object now bound to the name "a"

In Python, the value of objects depends on the context in which it is
evaluated. But when you do that, you're not getting a value that is
equivalent to object, but of some property of the object. The object
has no intrinsic value until it is evaluated. In that sense, and as
used by the python docs, I would say that the value of the object a is
"true" -- you can use it in boolean expressions, and it will evaluate
as such.

> I would say that in Python, objects do not have values.
> Objects are values.

You can say that, but if you do you're using some definition of
"value" that's only applicable in Python and programming languages
which behave the same way. It would be more correct to say that an
object is a collection of arbitrary data, which has a type and an
identity, and that the data in that collection has a value that
evaluates in context. An object is an abstract collection of data,
and abstractions have no value. You can not measure them in any
meaningful way. The data contained in the collection does, however,
have a value. When you reference an object in an expression, what you
get is not the value of the object, but the value of some peice of
data about, or contained in, that object.

It is this property of objects, that the value evaluated depends on
the context, that I think demonstrates that an object is *not* a
value. Values never change, as we've said in this thread: 3 is always
3. 'a' is always 'a'. But an object x can evaluate to many different
values, depending on how it is used. The definition of the object
would need to allow for it to do so, but Python allows that, and even
encourages it.

Steven D'Aprano

unread,
Aug 30, 2009, 2:37:38 PM8/30/09
to
On Sun, 30 Aug 2009 12:04:45 -0500, Derek Martin wrote:

> On Sun, Aug 30, 2009 at 03:42:06AM -0700, Paul McGuire wrote:
>> Python binds values to names. Always.
>
> No, actually, it doesn't. It binds *objects* to names. This
> distinction is subtle, but important, as it is the crux of why this is
> confusing to people. If Python is to say that objects have values, then
> the object can not *be* the value that it has, because that is a
> paradoxical self-reference. It's an object, not a value.

You're thinking about this too hard and tying yourself in knots trying to
philosophise about it. In context of OO programming, the distinction
between objects and values is fuzzy, and it depends on the context: e.g.
if I have this:

class MyInt(int):
pass

five = MyInt(5)
five.thingy = 23

is thingy part of the value of the object or not?

For most objects, at least for built-ins, the object *is* the value. (For
custom classes you create yourself, you are free to do anything you
like.) There's no need to try to distinguish between the object 3 and the
value of the object 3: you're looking for a distinction that simply
doesn't matter.


>> Is it any odder that 3 is an object than that the string literal
>> "Hello, World!" is an object?
>
> Yes. Because 3 is a fundamental bit of data that the hardware knows how
> to deal with, requiring no higher level abstractions for the programmer
> to use it (though certainly, a programming language can provide them, if
> it is convenient). "Hello, World!" is not. They are fundamentally
> different in that way.

Nonsense on two levels.

Firstly, in Python, *both* 3 and "Hello World" are complex objects, and
neither are even close to the fundamental bits of data that the hardware
can deal with.

Secondly, in low level languages, both are nothing but a sequence of
bytes, and hardware knows how to deal with bytes regardless of whether
they are interpreted by the human reader as 3 or "Hello World". The
compiler might stop you from adding 2371 to "Hell" or "o Wor" but the
hardware would be perfectly happy to do so if asked.

>> For a Python long-timer like Mr. D'Aprano, I don't think he even
>> consciously thinks about this kind of thing any more; his intuition has
>> aligned with the Python stars, so he extrapolates from the OP's
>> suggestion to the resulting aberrant behavior, as he posted it.
>
> I'm sure that's the case. But it's been explained to him before, and
> yet he still can't seem to comprehend that not everyone immediately gets
> this behavior, and that this is not without good reason.

Oh, it's obvious that not everybody gets this behaviour. I understand
full well that it's different to some other languages, but not all, and
so some people have their expectations violated.


> So, since it *has* been explained to him before, it's somewhat
> astonishing that he would reply to zaur's post, saying that the behavior
> zaur described would necessarily lead to the insane behavior that Steven
> described. When he makes such statements, it's tantamount to calling
> the OP an idiot.

Given Python's programming model and implementation, the behaviour asked
for *would* lead to the crazy behaviour I described.

(For the record, some early implementations of Fortran allowed the user
to redefine literals like that, and I'm told that Lisp will do so too.)

So what Zaur presumably saw as a little tiny difference is in fact the
tip of the iceberg of a fairly major difference. I don't know how smart
he is, but I'd be willing to bet he hadn't thought through the full
consequences of the behaviour he'd prefer, given Python's execution
model. You could make a language that behaved as he wants, and I wouldn't
be surprised if Java was it, but whatever it is, it isn't Python.


> I find that offensive,

It's moments like this that I am reminded of a quote from Stephen Fry:

"You're offended? So f***ing what?"

Taking offense at an intellectual disagreement over the consequences of
changes to a programming model is a good sign that you've got no rational
argument to make and so have to resort to (real or pretend) outrage to
win points.


> especially considering that
> Steven's post displayed an overwhelming lack of understanding of what
> the OP was trying to say.

I'm pretty sure I do understand what the OP was trying to say. He
actually managed to communicate it very well. I think he expects to be
able to do this:

>>> n = 1
>>> id(n)
123456
>>> n += 1
>>> assert n == 2
>>> id(n)
123456

Do you disagree? What do *you* think he wants?

--
Steven

Message has been deleted

Carl Banks

unread,
Aug 30, 2009, 4:52:29 PM8/30/09
to

*You* find something unfamiliar, and by your logic that means it's
unintuitive for everyone?

Nice logic there, chief. Presumptuous much?


Carl Banks

Piet van Oostrum

unread,
Aug 31, 2009, 6:04:01 AM8/31/09
to
>>>>> Derek Martin <co...@pizzashack.org> (DM) wrote:

>DM> On Sun, Aug 30, 2009 at 03:42:06AM -0700, Paul McGuire wrote:

>>> Is it any odder that 3 is an object than that the string literal
>>> "Hello, World!" is an object?

>DM> Yes. Because 3 is a fundamental bit of data that the hardware knows
>DM> how to deal with, requiring no higher level abstractions for the
>DM> programmer to use it (though certainly, a programming language can
>DM> provide them, if it is convenient). "Hello, World!" is not. They are
>DM> fundamentally different in that way.

How the semantics of Python is defined is not dependent of the hardware.
You could imagine a computer where strings are as much built into the
hardware as ints are. On the other hand you could also imagine a
computer that only knows about bits and where int arithmetic has to be
done in software. In fact early microprocessors only could operate
directly on bytes and arithmetic of larger ints was in software. And
even nowadays there are processors in use that don't have built-in
floating point hardware. Would you say that considering whether 3.14 is
an object in Python or whether that is to be considered strange should
depend on the availability of a floating point unit in the hardware
where the program runs? Would that make floating point numbers
"fundamentally different" from ints in the sense described above?
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: pi...@vanoostrum.org

zaur

unread,
Aug 31, 2009, 1:21:22 PM8/31/09
to
On 29 авг, 16:45, zaur <szp...@gmail.com> wrote:
> Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
> Type "copyright", "credits" or "license()" for more information.>>> a=1
> >>> x=[a]
> >>> id(a)==id(x[0])
> True
> >>> a+=1
> >>> a
> 2
> >>> x[0]
>
> 1
>
> I thought that += should only change the value of the int object. But
> += create new.
> Is this intentional?

As a result of this debate is not whether we should conclude that
there should be two types of integers in python: 1) immutable numbers,
which behave as constant value; 2) mutable numbers, which behave as
variable value?

Carl Banks

unread,
Aug 31, 2009, 1:59:41 PM8/31/09
to

You are free to use third-party modules (such as numpy) which provide
mutable numbers.

I see no reason to include any mutable number type standard library,
as not many people will require the performance benefits and/or
indirection of mutable numbers, and those who do are free to use third-
party modules that provide them.


Carl Banks

Steven D'Aprano

unread,
Aug 31, 2009, 7:31:14 PM8/31/09
to
On Mon, 31 Aug 2009 10:21:22 -0700, zaur wrote:

> As a result of this debate is not whether we should conclude that there
> should be two types of integers in python: 1) immutable numbers, which
> behave as constant value; 2) mutable numbers, which behave as variable
> value?

What can you do with mutable numbers that you can't do with immutable
ones, and why do you want to do it?

--
Steven

zaur

unread,
Sep 1, 2009, 10:04:09 AM9/1/09
to
On 1 сен, 03:31, Steven D'Aprano <st...@REMOVE-THIS-

Mutable numbers acts as variable quantity. So when augmented
assignment is used there is no need to create a new number object in
every binary operation.

But when I looked now into source of python int (longobject.c) I
realized that direct implementation of mutable int will not give any
benefit against defining proxy int class, which supports mutability.

Piet van Oostrum

unread,
Sep 1, 2009, 1:40:38 PM9/1/09
to
>>>>> zaur <szp...@gmail.com> (z) wrote:

>z> On 29 авг, 16:45, zaur <szp...@gmail.com> wrote:
>>> Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
>>> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
>>> Type "copyright", "credits" or "license()" for more information.>>> a=1
>>> >>> x=[a]
>>> >>> id(a)==id(x[0])
>>> True
>>> >>> a+=1
>>> >>> a
>>> 2
>>> >>> x[0]
>>>
>>> 1
>>>
>>> I thought that += should only change the value of the int object. But
>>> += create new.
>>> Is this intentional?

>z> As a result of this debate is not whether we should conclude that
>z> there should be two types of integers in python: 1) immutable numbers,
>z> which behave as constant value; 2) mutable numbers, which behave as
>z> variable value?

Numbers are immutable by nature (math). The number 3.14 remains 3.14
whatever you try to do with it. What you call an immutable number is in
fact a container that contains a number. You can change the contents of
the container, not by modifying the number in it but by replacing it
with a different number. Python has sufficient mechanisms for creating
these containers: lists, dictionaries, objects. If you think they are
not good enough then write a new one in C.

Steven D'Aprano

unread,
Sep 1, 2009, 7:00:06 PM9/1/09
to
On Tue, 01 Sep 2009 07:04:09 -0700, zaur wrote:

> On 1 сен, 03:31, Steven D'Aprano <st...@REMOVE-THIS- cybersource.com.au>
> wrote:
>> On Mon, 31 Aug 2009 10:21:22 -0700, zaur wrote:
>> > As a result of this debate is not whether we should conclude that
>> > there should be two types of integers in python: 1) immutable
>> > numbers, which behave as constant value; 2) mutable numbers, which
>> > behave as variable value?
>>
>> What can you do with mutable numbers that you can't do with immutable
>> ones, and why do you want to do it?
>>
>> --
>> Steven
>
> Mutable numbers acts as variable quantity.

So do immutable numbers bound to a name.


> So when augmented assignment
> is used there is no need to create a new number object in every binary
> operation.

"No need", sure, but there's no *need* to use object oriented code in the
first place, or garbage collectors, or high level languages, or even
functions. People got by with GOTO and assembly for years :) We use all
these things because they make *programming* easier, even if it adds
runtime overhead.

I'm asking what *problem* you are trying to solve with mutable numbers,
where immutable numbers are not satisfactory. The only answer I can
imagine is that you're worried about the overhead of creating new integer
objects instead of just flipping a few bits in an existing integer
variable.


--
Steven

Carl Banks

unread,
Sep 1, 2009, 7:43:06 PM9/1/09
to
On Sep 1, 10:40 am, Piet van Oostrum <p...@cs.uu.nl> wrote:
> >>>>> zaur <szp...@gmail.com> (z) wrote:
> >z> On 29 авг, 16:45, zaur <szp...@gmail.com> wrote:
> >>> Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
> >>> [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
> >>> Type "copyright", "credits" or "license()" for more information.>>> a=1
> >>> >>> x=[a]
> >>> >>> id(a)==id(x[0])
> >>> True
> >>> >>> a+=1
> >>> >>> a
> >>> 2
> >>> >>> x[0]
>
> >>> 1
>
> >>> I thought that += should only change the value of the int object. But
> >>> += create new.
> >>> Is this intentional?
> >z> As a result of this debate is not whether we should conclude that
> >z> there should be two types of integers in python: 1) immutable numbers,
> >z> which behave as constant value; 2) mutable numbers, which behave as
> >z> variable value?
>
> Numbers are immutable by nature (math). The number 3.14 remains 3.14
> whatever you try to do with it. What you call an immutable number is in
> fact a container that contains a number.

I wouldn't agree with that terminology or logic.

First of all "mutable number" is really just a short way to say
"mutable number object". A number object in Python is not a number,
it's just a representation of a number. Even if numbers are immutable
by nature, an object representing a number need not be.

And if your number object is mutable, it does not make that object a
container, at least not what I would call a container. A container
you have to dereference somehow to get at the object inside, whereas a
mutable number object you don't dereference: it acts like number as-
is.

IOW, the first example below is a container, the second is not:

num = [2]
num[0] += 3

num = mutable_int(2)
num += 3

(If you want to call the mutable number a container anyway, fine with
me, I am not here to bicker.) A container is sufficient to get a
layer of indirection if that's what you want the mutable number for.

However, the mutable number has a performance advantage over using a
container: it avoids the overhead of creating a new object. If you
were using += in a loop like this, it could turn out to be significant
savings. But since that's not common in Python I'd have to agree that
this optimization opportunity is best done with a third-party C-
extension, and not the standard library.


Carl Banks

Terry Reedy

unread,
Sep 1, 2009, 8:00:16 PM9/1/09
to pytho...@python.org
Steven D'Aprano wrote:
>
> I'm asking what *problem* you are trying to solve with mutable numbers,
> where immutable numbers are not satisfactory. The only answer I can
> imagine is that you're worried about the overhead of creating new integer
> objects instead of just flipping a few bits in an existing integer
> variable.

Of course, *because ints are immutable*, an implementation can avoid the
overhead of object creation for common cases by creating an array of
small integers.

CPython currently does this for -10 (or -5?) to about 256 or 257. I
would not be surprised if this coevers at least 80% of int.__new__ requests.

tjr

Steven D'Aprano

unread,
Sep 1, 2009, 11:48:43 PM9/1/09
to
On Tue, 01 Sep 2009 16:43:06 -0700, Carl Banks wrote:

>> Numbers are immutable by nature (math). The number 3.14 remains 3.14
>> whatever you try to do with it. What you call an immutable number is in
>> fact a container that contains a number.
>
> I wouldn't agree with that terminology or logic.

Abstract numbers aren't really "things", they're concepts, and as such I
don't think mutable or immutable has any meaning. But if it does, then
abstract numbers are immutable, because you can't change one into two
without losing the value one, and that certainly doesn't happen.


> First of all "mutable number" is really just a short way to say "mutable
> number object".

Yes, but "object" in the above doesn't necessarily mean object in the
sense of object-oriented programming. Perhaps a better word is "mutable
number thing", where "thing" could be an object in the OOP sense, or a
variable in the memory-location sense, or on a stack, in a register, or
chalk marks on a whiteboard.


> A number object in Python is not a number, it's just a
> representation of a number. Even if numbers are immutable by nature, an
> object representing a number need not be.

/s/number/abstract number/


Given that, then I agree, but given Python's implementation, you would
need more than one change to make number's mutable, and what you would
have wouldn't be Python any more.


> And if your number object is mutable, it does not make that object a
> container, at least not what I would call a container. A container you
> have to dereference somehow to get at the object inside, whereas a
> mutable number object you don't dereference: it acts like number as- is.

Agreed, so long as we're talking from the programmer's perspective. From
the compiler's perspective, or the Virtual Machine's perspective,
variables of the type "value stored at memory location" are a kind of
container: you don't dereference anything, but the compiler does.

There are multiple perspectives which are valid at once, depending on
where you're looking from. A *name* is kind of a container (but not in
the same sense that lists and dicts are containers), in that the VM has
to dereference the name to get to the object.


> IOW, the first example below is a container, the second is not:

Do you mean the name `num` is a container, or the *contents* of `num` is
a container? I assume you mean the contents.

> num = [2]
> num[0] += 3
>
> num = mutable_int(2)
> num += 3

In the sense of container that you give, I agree. But there's nothing
magic about mutable_int() in the above -- num could be bound to a regular
int, and it still wouldn't be a container. Obviously.

> (If you want to call the mutable number a container anyway, fine with
> me, I am not here to bicker.) A container is sufficient to get a layer
> of indirection if that's what you want the mutable number for.
>
> However, the mutable number has a performance advantage over using a
> container: it avoids the overhead of creating a new object.

You're assuming that the overhead of flipping bits is less than the
overhead of creating a new object, and that's almost certainly valid if
the VM is implemented in (say) C. But it may not be the case if the VM is
implemented in (say) Python, or Javascript, in which case "create a new
object" might be less expensive than "flip a bunch of bits". If you can
get the CPU to flip your bits, that will be fast, but perhaps your
implementation needs to convert the int to a string of ones and zeroes,
then perform bit-operations on those, then convert back to a real int.

(I mention this as a theoretical issue, not a serious objection to the
existing CPython implementation. But perhaps the PyPy people have to deal
with it?)


--
Steven

Tim Roberts

unread,
Sep 2, 2009, 3:07:27 AM9/2/09
to
Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> wrote:

>On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote:
>
>> I thought that int as object will stay the same object after += but with
>> another integer value. My intuition said me that int object which
>> represent integer value should behave this way.
>
>If it did, then you would have this behaviour:
>
>>>> n = 3 # bind the name n to the object 3
>>>> saved_id = id(n) # get the id of the object
>>>> n += 1 # add one to the object 3
>>>> assert n == 4 # confirm that it has value four
>>>> assert id(n) == saved_id # confirm that it is the same object
>>>> m = 3 # bind the name m to the object 3
>>>> print m + 1 # but object 3 has been modified
>5
>
>This would be pretty disturbing behaviour, and anything but intuitive.

Yes, indeed, and it's quite possible to write code like this in Fortran
that produces exactly this result -- an integer constant gets modified.

This used to get big yucks when we gathered around the keypunch, before we
had the Obfuscated C Contest to amuse us.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Piet van Oostrum

unread,
Sep 2, 2009, 4:45:09 AM9/2/09
to
>>>>> Carl Banks <pavlove...@gmail.com> (CB) wrote:

>CB> On Sep 1, 10:40�am, Piet van Oostrum <p...@cs.uu.nl> wrote:
>>>
>>> Numbers are immutable by nature (math). The number 3.14 remains 3.14
>>> whatever you try to do with it. What you call an immutable number is in
>>> fact a container that contains a number.

>CB> I wouldn't agree with that terminology or logic.

>CB> First of all "mutable number" is really just a short way to say
>CB> "mutable number object". A number object in Python is not a number,
>CB> it's just a representation of a number. Even if numbers are immutable
>CB> by nature, an object representing a number need not be.

Yes, that remark I made was more on the meta level.

>CB> And if your number object is mutable, it does not make that object a
>CB> container, at least not what I would call a container. A container
>CB> you have to dereference somehow to get at the object inside, whereas a
>CB> mutable number object you don't dereference: it acts like number as-
>CB> is.

If you read the OP, that was exactly what the OP (human) expected. That
the list would contain some kind of reference to the number. And then of
course you would have to dereference it to get the number.

>CB> IOW, the first example below is a container, the second is not:

>CB> num = [2]
>CB> num[0] += 3

>CB> num = mutable_int(2)
>CB> num += 3

>CB> (If you want to call the mutable number a container anyway, fine with
>CB> me, I am not here to bicker.) A container is sufficient to get a
>CB> layer of indirection if that's what you want the mutable number for.

>CB> However, the mutable number has a performance advantage over using a
>CB> container: it avoids the overhead of creating a new object. If you
>CB> were using += in a loop like this, it could turn out to be significant
>CB> savings. But since that's not common in Python I'd have to agree that
>CB> this optimization opportunity is best done with a third-party C-
>CB> extension, and not the standard library.

That's an implementation detail.

Carl Banks

unread,
Sep 2, 2009, 8:40:51 AM9/2/09
to

Many Fortran compilers these days pass scalars by value by default.

Recently I had to compile a cicra-1972 Fortran program where I had to
disable a lot of recent Fortran innovations (like from 1977) to get it
to build properly. It turned out that it did try to modify a constant
somewhere, but then it segfaulted because the compiler put that
constant in read-only memory.

(Whoever wrote the program originally was a smart cookie, BTW, it was
super versatile for its time.)


Carl Banks

Message has been deleted
0 new messages