A question on modification of a list via a function invocation

Steve D'Aprano steve+python at pearwood.info
Tue Sep 5 22:51:48 EDT 2017


On Tue, 5 Sep 2017 11:11 pm, Gregory Ewing wrote:

> Steve D'Aprano wrote:
>> The third entity is the reference linking the name to the object (the arrow).
>> This isn't a runtime value in Python, nor is it a compile time entity that
>> exists in source code. It is pure implementation, and as such, exists outside
>> of the Python domain.
> 
> The fact that there is a connection between the name and the
> object is very much part of Python's abstract semantics.
> 
> There are different ways to implement that connection, but
> *any* implementation of Python has to include *some*
> representation of it.

Any *what* of Python? Oh, that's right, you said any *implementation* of Python.

Isn't that what I said? That references are a property of the implementation,
not of the language. You are inadvertently agreeing with me.

- You can't bind a reference to a name in Python. Names are always bound to
objects. 

- You can't have a list or set of references, only lists or sets of objects.

- You can't form a reference to a reference.

- You can't use references to implement pass-by-reference semantics.

- You can't view or inspect references in Python (maybe in ctypes, 
  or in a debugger, but those aren't part of the Python language, 
  they are implementation-specific interfaces to the interpreter).


So in what sense are references part of the Python language?

My answer is that they are not. They're a part of the implementation, which
makes them different from values (ints, floats, strings, lists, and other
objects, whether built-in or not). It makes them different from other
conceptual entities in Python like for-loops, comprehensions, try...except
blocks etc, which aren't values but they are properties of the program (at
least of the source code, if not the byte code).


> There are also different words that can be used to describe
> it. You can say that names are bound to objects, or that
> names refer to objects, or that names hold references to
> objects.

As they used to say in Sesame Street, "One of these things is not like the
others..."


The first two describe a *relationship* between two entities, the name and the
object: being bound to, referring to, are verbs which indicate a relationship.

The third introduces a third entity. There's now two relationships:

- names hold (are bound to, point to) references;

- references refer to (are bound to, point to) objects.

That's an example of reification, "making real", taking an abstract concept or
relationship or verb and treating it as a thing. We often do that in poetic
language: we talk of death or hunger stalking the streets.

In this case, its a bit more complicated because *in a sense* you are right.
Inside the interpreter, there really is a data structure which we might call a
reference: in CPython its a pointer. So you are not entirely being poetic here.
Inside the interpreter, you (probably?) could print out the value of the
pointer, or manipulate it in some fashion.

But at the level of Python code, you are reifying a relationship into a thing.
In Python code, names are bound to objects, and the implementation of that
binding is not part of the language itself. References aren't things, any more
than fatherhood or treason are things (they are states of being that describe a
certain relationships).

That's because Python describes a virtual machine which is abstracted further
away from the machine than C. Part of that abstraction is to remove pointers
(references) from the set of values available to Python code to manipulate.


> These are all equally good ways of talking about 
> the exact same abstract concept.

No they aren't equally good, not if they lead to confusion and terminology
abuse. Earlier I linked to a Stackoverflow question about Java, asking how to
find the address of variables. It must be easy, right, because Java variables
hold pointers to some address. (Actually, no they don't.)

In Python, we still have people asking from time to time how to dereference
pointers (references), or how to pass an int by reference, or a list by value
(making a copy). It must be possible, because Python is pass-by-value for some
values and pass-by-reference for others, right? (No.)

I'm not opposed to the "reference" concept in general. I just want people to be
more clear about what level of abstraction you are talking about when you use
it. I don't want people to say that Python (the language) has references or
pointers, because it doesn't. I don't have any objection to people saying that
the interpreter has references or pointers, and that's how name binding works
behind the scenes, or under the hood.

And I categorically *hate* explanations of Python's argument parsing that
require people to simultaneously believe that the value of x following x=1 is:

    1

(the meaning of "value" they actually use in practice), and:

    some invisible, unknown, unknowable, implementation-dependent
    reference to the actual value

(the meaning they insist they believe in, purely so that they can justify their
abuse of terminology).



> To me this argument about whether Python has references
> or not is like an American person saying that cars have
> hoods, and a British person saying he's wrong, hoods
> are an implementation detail and cars actually have
> bonnets instead.


No, this isn't a mere argument about the name we give a thing. It is an argument
about:

- the level of abstraction in which we talk;

- in any specific level of abstraction, what counts as a thing or not;

- the importance of not misleading people by inappropriate or careless
  mixing of entities from different abstractions.


I don't care whether you want to call it a reference or a pointer or a woozle,
so long as your explanation is clear that it exists in the interpreter's
implementation, not in the Python language.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list