Terminology: “reference” versus “pointer”

Ben Finney ben+python at benfinney.id.au
Sat Sep 12 08:26:37 CEST 2015

Random832 <random832 at fastmail.com> writes:

> Ben Finney <ben+python at benfinney.id.au> writes:
> > The reference value is inaccessible to the program, it can only be
> > used to get at the referenced object.
> What does it mean to access something, if not to do some operation on
> it? Getting the referenced object is the operation you can do with it.

You've clearly committed to some ontology that just doesn't match the
Python data model.

The following are some of the axioms in Python's data model:

* All values are objects that persist over time.

* All objects have an immutable identity, that is guaranteed different
  from all other coexisting objects.

* The identity of an object has no particular relationship to the
  object's implementation or location [0], it is an abstract value that
  has no meaning other than uniquely identifying the object.

* The ‘id’ function returns the identity of the object passed as the
  parameter to the call.

* A name used to access an object is a reference to that object,
  equivalent to an item in a dictionary.

* A collection instance — a list, a dict, a set, etc. — contains
  references to objects, and provide access to those references via the
  container type's API.

If you don't agree with those, that's too bad, and it means there's not
much point continuing the discussion. I hope, therefore, that you do
agree with those axioms.

If you do agree with those, some corollaries follow:

* Container types do not contain objects.

  It is a useful analogy to say the objects are “in” the container; but
  that would imply they are not simultaneously in any other container.
  That's not true, so it's a flawed (though very useful) analogy.

* Names do not contain anything.

  They aren't what some other languages call “variables”. They are
  oblivious to the type of the value and can never exist except while
  referencing some object.

* References are not values.

  The reference obviously must have an implementation that deals with
  values, but those values are not available in Python. Each reference
  is inaccessible, hidden away; it is not a value, it is not an object.

> So, if you have a list x, and assign a new value to x[0], it doesn't
> change the list, because you can't compare the list to the value the
> list had before?

Yes, it changes the list. It doesn't change any of the references

The list's value is the sequence of references it contains. Removing one
reference changes the list's value; putting a different reference in the
collection changes the list's value.

None of that changes any reference, it just changes *which* references
are in the list.

The references themselves don't have any value accessible to Python.

> You're not making any sense. It's a value. Changing it and "throwing
> away and replacing with a different one" are the same thing.

Not true. To throw away one and replace it with another is to switch to
a different value with a different identity::

    >>> foo = 17     # One reference to the integer object.
    >>> bar = foo    # A different reference to the object.
    >>> id(foo) == id(bar)    # Are these references to the same object?
    >>> bar = 9               # Try to “change” the object.
    >>> id(foo) == id(bar)    # Is ‘bar’ still the same object?

To change a value is to keep the same identity::

    >>> foo = [17, 23, 42]    # One reference to the list object.
    >>> bar = foo             # A different reference to the object.
    >>> id(foo) == id(bar)    # Are these references to the same object?
    >>> id(foo[2]) == id(bar[2])  # How about the references contained in the list?
    >>> bar[2] = 9                # Try to “change” the object.
    >>> id(foo) == id(bar)        # Is ‘bar’ still the same object?

References aren't values, so their identity doesn't even feature in
Python's data model.

>From the point of view of a Python program, a reference *has no value*
(and no identity). It is just a metaphorical label, tag, or “sticky
note” one can invoke to make a specific object available.

> > That's significant, because unlike a mutable value you can never
> > again get at the old reference in the Python program.
> I don't understand what you mean by "can never again get at" it if you
> think you _can_ do it for mutable values.

In the above example, the different references originally created for
‘foo’ and ‘bar’ are inaccessible. ‘foo’ and ‘bar’ are not the same, they
are different references that happen to lead to the same object.

When ‘bar’ switches to a different reference, whatever reference it had
at prior points in time are gone for good. Any other references to the
same object continue on unaffected, because they are not the same

[0]: This axiom is unfortunately confused in the documentation's
  statement “you may think of it as the object’s address in memory”
  <URL:https://docs.python.org/3/reference/datamodel.html>. That's not a
  guarantee of the data model, it is merely meant to help the reader
  understand the concept.

  Note that the documentation deliberately does *not* say the identity
  is the object's address in memory except as a note about the
  *implementation* in CPython. That is not part of the data model.

 \          “It is well to remember that the entire universe, with one |
  `\   trifling exception, is composed of others.” —John Andrew Holmes |
_o__)                                                                  |
Ben Finney

More information about the Python-list mailing list