Explanation of list reference

M

Mark Lawrence

Then you are obliged to provide some other way of understanding object-identity

I have no interest in understanding object identity, I can write code
quite happily without it. If you (plural) are interested in
understanding this subject I hope you enjoy comparing the various Python
implementations while I'm *STILL* writing code.
 
M

Marko Rauhamaa

Chris Angelico said:
Because everything in Python is an object, and objects always are
handled by their references. This wouldn't be true in every language
(eg it's not true of Java's unboxed types), but it's intrinsic to
Python's object model.

Well, it's part of Python's reference model. Any model that produces
valid Python behavior is equally good. An implementation that boxes some
or all immutable objects would still be perfectly valid.

Anyway, an object is a fairly advanced and abstract concept. A beginning
programmer wouldn't be equipped to understand the ultimate abstraction;
an object is too all-encompassing to express anything. It might be
productive to lead the aspirant to the mountain summit through a more
concrete model. Identifying the references with RAM addresses and
objects with RAM snippets might keep object tangible for the first few
months, although a more mundane model would be welcome.

I'm reminded of Raymond Smullyan's excellent "To Mock the Mockingbird,"
which models combinatory logic with a forest full of chirping birds.


Marko
 
M

Marko Rauhamaa

Mark Lawrence said:
I have no interest in understanding object identity, I can write code
quite happily without it.

Luckily, what we are now debating is mostly terminology and points of
view where the outcomes are unaffected.

However, as an example, it is important to know if you should write:

if x is not None:
...

or if

if x != None:
...

is more robust.

As an aside, thousands upon thousands of Java programmers churn out code
quite happily with no interest in understanding the "happens before"
relation (<URL:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5>),
which is heavily leaned on by Hotspot's JIT optimizer. I find that
disconcerting.


Marko
 
C

Chris Angelico

This forum is read in many different contexts, and attachments aren't
appropriate. You should simply put the text directly into your message,
if it's short enough.

If it's long, then put it online somewhere and send a link with a
description; or, better, make it shorter so it is reasonable to put the
text in a message :)

I skimmed it, and... uhh... it's not text :) Well, it's mostly text,
but it's arranged on the page with positioning and arrows and stuff.
So a link would be more useful than trying to cram it into the post
itself.

ChrisA
 
S

Steven D'Aprano

I don't accept that as a counterexample.

Why? Do you think I lied and just faked the output I put into my post? It
is a clear case where two distinct objects, in this case 230000 and
420000, have the same ID.

You cut out the explanation I gave explaining the example, which is
crucial. Your description of identity leaves out a critical factor,
namely that the objects being discussed must exist simultaneously. If you
don't specify that factor, your description includes a great big hole,
just as I show above.

You will have to produce:

(id(x) == id(y)) == (x is y)

I don't have to produce anything of the sort. All I need to do is show a
case where two distinct objects have the same ID. That is quite easy in
CPython, since IDs can be re-used after objects are garbage-collected.

That's the point. I don't think id() and "is" have any abstract meaning
on top of the formal axioms.

Who is talking about "abstract meaning"? They have concrete meaning in
Python, and extremely simple meaning at that.

* id() is a function which returns an abstract implementation-
dependent identity number which is unique for each object
during the object's lifetime.

* The "is" operator compares the two operands for identity,
returning True if, and only if, they are the same object,
otherwise returning False.

Object identity is simple and well-defined in Python. I don't know why
you are so resistant to this. Read the documentation.
 
M

Marko Rauhamaa


Nowhere do I see the violating "x is y".
All I need to do is show a case where two distinct objects have the
same ID.

How do you know objects are "distinct"? Myself, I would use the "is"
test.
Who is talking about "abstract meaning"?

I am. I mean, "implementation-independent".
Object identity is simple and well-defined in Python. I don't know why
you are so resistant to this. Read the documentation.

It is not defined at all:

Every object has an identity, a type and a value. An object’s
identity never changes once it has been created; you may think of it
as the object’s address in memory. The ‘is‘ operator compares the
identity of two objects; the id() function returns an integer
representing its identity.

Thus "x and y are identical" *means* "x is y" and nothing else.


Marko
 
R

Roy Smith

Marko Rauhamaa said:
It is not defined at all:

Every object has an identity, a type and a value. An object’s
identity never changes once it has been created; you may think of it
as the object’s address in memory. The ‘is‘ operator compares the
identity of two objects; the id() function returns an integer
representing its identity.

The "you may think of it as the object's address in memory" part is
misleading, and should be removed from the docs. While it's true that
you may think of it that way, such thinking just leads you to make
assumptions which are not universally true.

I agree with Marko that this is not a definition. It's a collection of
random statements about ids, their use, and some misleading philosophy.
Even the part about "... compares the identify of two objects" is kind
of funky, since it implies that you do indeed have two objects!

A definition would be:

"The identity of an object is an integer which never changes during the
lifetime of the object, and which is guaranteed to be distinct from the
identities of all other objects with overlapping lifetimes. A given
identity may be reused for objects with disjoint lifetimes".

That (I think) says everything is which is guaranteed about identities,
and nothing more. Once you've defined what an identity is, then you can
go on to describe some fun things you can do with it:

"The id() function returns the identity of an object. The 'is' operator
compares the identities of its two operands and returns True if they are
the same."
 
I

Ian Kelly

Nowhere do I see the violating "x is y".

You formulated your rule as a rule of inference. The logical
inference from the above is that x is y, which is false even if it
can't be directly tested in Python.
How do you know objects are "distinct"? Myself, I would use the "is"
test.

Eliding over details of how one knows that both of the literals above
create objects, if the objects are separately created, then they are
distinct objects.
I am. I mean, "implementation-independent".


It is not defined at all:

Every object has an identity, a type and a value. An object's
identity never changes once it has been created; you may think of it
as the object's address in memory. The 'is' operator compares the
identity of two objects; the id() function returns an integer
representing its identity.

Thus "x and y are identical" *means* "x is y" and nothing else.

This notion of identity sounds useless, and if that is the way you
prefer to understand it then you can safely ignore that it exists. I
think that most users though inherently understand the concept of
objects being distinct or identical and see the value in being able to
test for this.
 
R

Rustom Mody

Steven D'Aprano :
Marko Rauhamaa
The "you may think of it as the object's address in memory" part is
misleading, and should be removed from the docs. While it's true that
you may think of it that way, such thinking just leads you to make
assumptions which are not universally true.
I agree with Marko that this is not a definition. It's a collection of
random statements about ids, their use, and some misleading philosophy.
Even the part about "... compares the identify of two objects" is kind
of funky, since it implies that you do indeed have two objects!
A definition would be:
"The identity of an object is an integer which never changes during the
lifetime of the object, and which is guaranteed to be distinct from the
identities of all other objects with overlapping lifetimes. A given
identity may be reused for objects with disjoint lifetimes".
That (I think) says everything is which is guaranteed about identities,
and nothing more. Once you've defined what an identity is, then you can
go on to describe some fun things you can do with it:

Thanks! -- Nice to hear slightly more philosophically astute attempt than
the naivete going around: "Object?! We all know whats an object!
Everyone knows whats an object!!"

However I am betting that the problem remains. Youve transfered the identity
question into the lifetime.

Now define object-lifetime without reference to identity :)

[Incidentally same applies to Ian's attempt at reducing identity to creation]

Just staying with 'lifetime' and the original meaning from which this word
was analogized. (Allegorized?)

I am supposed to be about 50 years old.
What exactly does that mean?
The cells in my body recycle every few months -- couple of years if we add bones
The molecules that make up those cells are as old as the universe.

What exactly does that 50 refer to?
"The id() function returns the identity of an object. The 'is' operator
compares the identities of its two operands and returns True if they are
the same."

Thats good -- 'is' in terms of 'id' -- better than the obfuscation and
prevarication of the other way round. Only the name id is misleading -- it
should be machine-id or some such.

Consider these examples:

Two graphs are the same if they have the same no of vertices and
there is a mapping f from one vertex set to the other such that
vw is edge in graph1 iff f(v)f(w) is edge in graph2.

For a mathematician such an identity is unexceptionable
The only catch is that implementing such an identity requires
finding the f and that is NP complete.

Even worse...
Two functions f and g are the same (from a math pov)
if ∀ x y . f(x) = g(y)

Now I define
def f(x) : return x+x
def g(x) : return 2*x

If a python (or any such) implementation could 'solve'
f==g ∀ f,g, it could also 'solve'
f == h
where h is
def h(x) : return h(x)
which is the halting problem

Moral?
The meaning of identity is very dependent on framing and has
no 'single' 'obvious' 'most natural' answer.
Given that we are (hopefully!) programmers, a machine-oriented framing seems
appropriate
 
R

Rustom Mody

Steven D'Aprano:
It is not defined at all:

In a certain way thats what I am saying. But you are saying it
stronger than I would... See below
Every object has an identity, a type and a value. An object's
identity never changes once it has been created; you may think of it
as the object's address in memory. The 'is' operator compares the
identity of two objects; the id() function returns an integer
representing its identity.
Thus "x and y are identical" *means* "x is y" and nothing else.

Formally yes.

But in practice, we (where we means experienced programmers and
presumably excludes persons like the OP) understand identity
'somehow-or-other'

What does that 'somehow-or-other' consist of?

I would argue that we do that comprehending-act by translating to
a kind of C. Maybe an informal, pidgin C but close enough that we get
(something of) the semantics.
 
I

Ian Kelly

Thanks! -- Nice to hear slightly more philosophically astute attempt than
the naivete going around: "Object?! We all know whats an object!
Everyone knows whats an object!!"

However I am betting that the problem remains. Youve transfered the identity
question into the lifetime.

Now define object-lifetime without reference to identity :)

Fundamentally that's what definitions do. They transfer the question
of "what is X" to "okay, so what is this thing that defines X". All
definitions must ultimately be circular, simply because we have only
finitely many words and concepts to work with.
Thats good -- 'is' in terms of 'id' -- better than the obfuscation and
prevarication of the other way round. Only the name id is misleading -- it
should be machine-id or some such.

Consider these examples:

Two graphs are the same if they have the same no of vertices and
there is a mapping f from one vertex set to the other such that
vw is edge in graph1 iff f(v)f(w) is edge in graph2.

For a mathematician such an identity is unexceptionable

Is it though? If we were to play the same game with it, I could point
out that you haven't defined graph. So I'll retrieve a definition
from Wikipedia:

"""
a graph is an ordered pair G = (V, E) comprising a set V of vertices
or nodes together with a set E of edges or lines, which are 2-element
subsets of V
"""

Well, that's great, but it just transfers the definition of graph into
the definition of an ordered pair. Ordered pairs can be defined in
terms of sets:

"""
In 1921 Kazimierz Kuratowski offered the now-accepted definition of
the ordered pair (a, b):

(a, b) := {{a}, {a, b}}
"""

But what is a set? Cantor offers this definition:

"""
A set is a gathering together into a whole of definite, distinct
objects of our perception [Anschauung] or of our thought - which are
called elements of the set.
"""

But what precisely are "objects" and how are we to determine their
distinctness? Cantor above relates them to perception or thought, but
surely my own perception and thought differ from Cantor's. If
mathematics or philosophy offer us any absolute answer to this
question, I'm unable to find it.
 
I

Ian Kelly

But what is a set? Cantor offers this definition:

"""
A set is a gathering together into a whole of definite, distinct
objects of our perception [Anschauung] or of our thought - which are
called elements of the set.
"""

But what precisely are "objects" and how are we to determine their
distinctness? Cantor above relates them to perception or thought, but
surely my own perception and thought differ from Cantor's. If
mathematics or philosophy offer us any absolute answer to this
question, I'm unable to find it.

I sent the last message a little too early. To continue: the above
definition of set is an informal one. In axiomatic set theory, it
turns out that "set" is simply taken as an undefined primitive. In
other words: "Set?! We all know what's a set!
Everyone knows what's a set!!"

At some level we have to have primitives, and while we can at some
level delve into the machine in order to define an object in terms of
memory location and layout and lifetime and even physical
considerations such as "which memory?"; at the level of the Python
abstraction I suggest that an object is simply an undefined primitive.
 
G

Grant Edwards

With the restrictions of computer memory, I suspect that two objects
with the same address must be identical,

That's true if they have the same address _at_the_exact_same_time_.

[AND IF the two chunks of code evaluating the addresses of the objects
share a machine-level address space -- which I doubt is actually
required by the Python language definition. It would be difficult
(but not impossible) to implement a Python where that wasn't true.]

However, it's possible for object 1 to have address XYZ at one point
in time and object 2 to have address XYZ at a different point in time
even though object 1 and object 2 are different objects.

The tricky bit is that those two points in time may occur at adjacent
"lines" when your program is executing. They may even occur at two
different points within the same line of code. IOW, there's just no
reason to assume that:

address_of(object1) == address_of(ojbect2)

is equivalent to

object1 is object2

Garbage collection could kick in after the evaluation of
address_of(object1) and before the evaluation of address_of(object2)
with the result that the two objects would appear to have the same
address in memory.

So, unless you're working on the guts of a Python implementation
you've got to just plain stop thinking about memory addresses.
Period.
 
S

Steven D'Aprano

The "you may think of it as the object's address in memory" part is
misleading, and should be removed from the docs. While it's true that
you may think of it that way, such thinking just leads you to make
assumptions which are not universally true.

I agree with Marko that this is not a definition. It's a collection of
random statements about ids, their use, and some misleading philosophy.
Even the part about "... compares the identify of two objects" is kind
of funky, since it implies that you do indeed have two objects!

Correct, it should say "two operands" to be pedantic.

But in regular English, it is quite normal to say things like "the two
people actually turned out to be same person" (say, Superman and Clark
Kent) and I see no reason not to allow the similar, technically sloppy
but easily understandable idea that the `is` operator tests whether two
objects are in fact the same object.

This concept isn't really that hard to understand. In the expression `a
is b`, you have an object bound to the name "a", an object bound to the
name "b", hence *two objects*, and you want to know if they are the same
object or not.

A definition would be:

"The identity of an object is an integer which never changes during the
lifetime of the object, and which is guaranteed to be distinct from the
identities of all other objects with overlapping lifetimes. A given
identity may be reused for objects with disjoint lifetimes".

You then go on to say:
"The id() function returns the identity of an object. ..."


This definition is wrong. An object's identity and its ID are not the
same. Objects in Python have an identity the instant they are created,
but they may not have an ID assigned to them until much later, if at all.
Both IronPython and Jython lazily assign IDs on request, not on creation.
Here's an example from Jython:
2


IronPython is similar, although the specific IDs may not be the same.


The problem here is that you are wrongly identifying an object's identity
with its identification number. That doesn't apply to people (if you are
American, your identity is not the same as your Social Security number);
it doesn't apply to rocks, or pencils, or kitchen spoons. Why should it
apply to Python objects? The identity of an object is an inherent,
fundamental aspect of the object's existence, not some label stuck to it.

In Jython, the `is` operator can distinguish objects without assigning
them an ID number:
8


In plain English, "identity" has various definitions, but the one needed
here is this:

The state or quality of being identical, or the same; sameness.
[Webster 1913]

where "identical" is understood in the strong sense of:

being the exact same one; not any other
[Wordnet 2006]


rather than the weak sense of merely looking the same, as in "identical
houses". These are common, ordinary words, and no more need specialist
definitions in the Python documentation than do the other common,
ordinary words used, such as "never", "changes" or "created".

An object's identity is that quality which distinguishes it from every
other object. The nature of that quality is not important. Not
withstanding such interesting but irrelevant philosophical questions as
the Paradox Of My Grandfather's Axe, the intuitive, common, plain-English
meaning of identity is all we need to understand object identity, because
it's the same meaning.
 
S

Steven D'Aprano

Nowhere do I see the violating "x is y".

Do you truly think that there is even the tiniest, most microscopic
chance that the int 230000 which has been garbage-collected and no longer
exists, and the int 420000, are the same object?


How do you know objects are "distinct"? Myself, I would use the "is"
test.

I know objects are distinct if they are objects with different values,
such as 230000 and 420000, due to the fundamental fact that ints cannot
have the value 230000 and 420000 at the same time. I leverage my
knowledge that ints are intended to model the mathematical integers, and
while that model is not perfect, it is not so bad as to have 230000 and
420000 be the same number.

I also know that objects are distinct if one of them has been garbage
collected, on the account of it no longer existing.

I am. I mean, "implementation-independent".

"Abstract meaning" does not mean "implementation independent". The
definition of identity given in the documentation is both implementation
independent and concrete: identity is tied concretely to the creation of
the object, while still leaving implementations free to choose exactly
how they tie identity to creation.

It is not defined at all:

Every object has an identity, a type and a value. An object’s
identity never changes once it has been created; you may think of it
as the object’s address in memory. The ‘is‘ operator compares the
identity of two objects; the id() function returns an integer
representing its identity.

Thus "x and y are identical" *means* "x is y" and nothing else.

You are correct, "x and y are identical" does mean that "x is y". That is
exactly the point.

However, the `is` operator is not necessarily the same as the English
word "is". Is some languages, the `is` operator is a synonym for the
equals operator. That is not the case in Python. In Python, the
*expression* `x is y` has the same meaning as the English sentence "x is
y" in the strong sense of testing identity, rather than the weak sense of
merely testing similarities (or metaphor). So the Python docs don't
merely give a circular definition, they distinguish between two different
and competing possibilities:

(1) The `is` operator means the same as the == operator. (NO)

(2) The `is` operator tests for object identity. (YES)


Please also see my response to Roy Smith's message.

Every object has a unique (during the lifetime of the object) identity.
The specific nature of that identity is implementation-dependent, and
strictly irrelevant. The `is` operator tests whether the two operands are
the same object, that is, whether they have the same identity. That's all
it does.
 
D

Dennis Lee Bieber

myobj.alist[12]["some key"].attribute


I think it is fair to call that both an expression and a reference.

It's a chain of references to me...

The name myobj is a reference to some object that has a component
(attribute) named alist which is a reference to a list object. [12]
selects an element of the list, said element being an anonymous (unnamed,
unless you want to consider [12] to be the name) reference to an unnamed
dictionary object. "some key" selects an element of the dictionary which is
an anonymous reference to an object having an attribute named attribute
which itself is a reference to some object -- for the purposes of this
chain, the final mentioned object is considered the value of the fully
qualified name.
 
M

Marko Rauhamaa

Ian Kelly said:
This notion of identity sounds useless, and if that is the way you
prefer to understand it then you can safely ignore that it exists. I
think that most users though inherently understand the concept of
objects being distinct or identical and see the value in being able to
test for this.

It is not useless to identify your fundamental definitions and axioms
instead of resorting to circular reasoning.

The original question was how a beginning programmer could "get" lists.
We very quickly descended into the murky waters of "objects" of an
underlying machine and CPython's way of implementing things. I was
wondering if there was a way to "get" integers, lists, references etc
without hauling the poor student under the keel.

In a word, could Python be your first programming language?


Marko
 
T

Terry Reedy

Whats the notion of object identity is the question.
Ok so you reject the memory addr as an 'implementation detail'
Then you are obliged to provide some other way of understanding object-identity

'Identity' is an abstraction. For immutable objects, it is essentially
irrelevant. For mutable objects, it is essential in the following sense.
A and B are the same object if mutating A necessarily mutates B and
different if they can be independently mutated.

The id() of an object is a fixed integer that is temporally unique. An
implementation might use the id to access objects. When one executes
Python mentally, one might skip implementing id(). Its main use is to
test an implementation. Most beginners should ignore it.
 
M

Marko Rauhamaa

Steven D'Aprano said:
Do you truly think that there is even the tiniest, most microscopic
chance that the int 230000 which has been garbage-collected and no
longer exists, and the int 420000, are the same object?

What were we talking about again?


Marko
 
I

Ian Kelly

It is not useless to identify your fundamental definitions and axioms
instead of resorting to circular reasoning.

The original question was how a beginning programmer could "get" lists.
We very quickly descended into the murky waters of "objects" of an
underlying machine and CPython's way of implementing things. I was
wondering if there was a way to "get" integers, lists, references etc
without hauling the poor student under the keel.

In a word, could Python be your first programming language?

Absolutely, many people learn Python as their first language. Even
MIT famously uses it for their introductory computer science class.
And I think that most of them do it without getting into internal
details like memory addresses and the heap.
 

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

Forum statistics

Threads
473,786
Messages
2,569,626
Members
45,328
Latest member
66Teonna9

Latest Threads

Top