What other languages use the same data model as Python?

122 views
Skip to first unread message

Steven D'Aprano

unread,
May 1, 2011, 4:45:51 AM5/1/11
to
Python uses a data model of "name binding" and "call by object" (also
known as "call by sharing"). I trust I don't need to define my terms, but
just in case:

http://effbot.org/zone/call-by-object.htm
http://effbot.org/zone/python-objects.htm


Now, this is different from languages like C and Pascal, which is based
on variables, or Forth, which explicitly manipulates a stack. Quite
often, when people want to impress upon others that Python is not C, they
will say:

"Python's data model is different from other languages"

which is perfectly correct, if you think of C as "other languages". But
it's equally correct to say that Python's data model is the same as other
languages. As I understand it, Python and Ruby have the same data model.
So does Java, so long as you only consider objects and ignore unboxed
native values. I believe (but could be wrong) that another language of
about the same vintage as Python, Emerald, also uses the same model.
That's not surprising, because I believe that Emerald (just like Python)
was strongly influenced by CLU.

What other languages use the same, or mostly similar, data model as
Python?

--
Steven

Alec Taylor

unread,
May 1, 2011, 5:00:27 AM5/1/11
to Steven D'Aprano, pytho...@python.org

Chris Rebert

unread,
May 1, 2011, 5:04:20 AM5/1/11
to Steven D'Aprano, pytho...@python.org
On Sun, May 1, 2011 at 1:45 AM, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
> Python uses a data model of "name binding" and "call by object" (also
> known as "call by sharing").
<snip>

> As I understand it, Python and Ruby have the same data model.
> So does Java, so long as you only consider objects and ignore unboxed
> native values. I believe (but could be wrong) that another language of
> about the same vintage as Python, Emerald, also uses the same model.
> That's not surprising, because I believe that Emerald (just like Python)
> was strongly influenced by CLU.
>
> What other languages use the same, or mostly similar, data model as
> Python?

According to http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
, besides those you already listed:
Scheme, OCaml, AppleScript, and possibly VB, among "many other languages".

I can't personally vouch for the accuracy of this.

Cheers,
Chris

Terry Reedy

unread,
May 1, 2011, 3:10:11 PM5/1/11
to pytho...@python.org
On 5/1/2011 4:45 AM, Steven D'Aprano wrote:
> Python uses a data model of "name binding" and "call by object"
> (also known as "call by sharing"). I trust I don't need to define my
> terms, but just in case:
>
> http://effbot.org/zone/call-by-object.htm
> http://effbot.org/zone/python-objects.htm
>
>
> Now, this is different from languages like C and Pascal, which is
> based on variables,

Or Fortran or Basic (and I suspect, but do not know, Algol) and other
descendents: Ada?, PL/1?). In statistical languages, user-defined names
typically refer to typed data columns (eash a set of storage locations)
or user-defined functions.

> "Python's data model is different from other languages"
>
> which is perfectly correct, if you think of C as "other languages".
> But it's equally correct to say that Python's data model is the same
> as other languages.

You defined Python's 'data model' as having two aspects: 'name binding'
and 'call by object'. A language could match one but not the other. I
believe Lisps have name-binding, but I know not all only have
call-object. Macro calls (and earlier predecessors) are call-by-code-text.

As I understand it, Python and Ruby have the same
> data model. So does Java, so long as you only consider objects and
> ignore unboxed native values. I believe (but could be wrong) that
> another language of about the same vintage as Python, Emerald, also
> uses the same model. That's not surprising, because I believe that
> Emerald (just like Python) was strongly influenced by CLU.

While Guido does not, that I know of, credit CLU as Python's direct
inspiration, I think it (and Barbara Liskov) as the originator of
Python's data model. I believe she thought of the call-by-object
semantics as something of an innovation.

> What other languages use the same, or mostly similar, data model as
> Python?

Natural languages. That is why I think it is better to think of Python
as an algorithm language or information-object manipulation language
rather than as just a linear-memory machine language. A linear memory
with bytes addressed from 0 to max-int or max-long is an explicit part
of the definition of assembly languages and C. It is no part of the
definition of Python.

Nice begin-a-thread post.

--
Terry Jan Reedy

Gregory Ewing

unread,
May 1, 2011, 6:33:08 PM5/1/11
to
Steven D'Aprano wrote:

> Python uses a data model of "name binding" and "call by object" (also
> known as "call by sharing").

It can be summed up in a less jargony way by saying that all
data is stored in heap-allocated objects, and variables refer
to objects rather than containing them directly. Everything
else follows from that.

> What other languages use the same, or mostly similar, data model as
> Python?

Pretty much any dynamically-typed language: Lisp, Scheme,
Smalltalk, Snobol, Icon, Postscript, Ruby, Lua, ...

Some languages have it for some data types but not others.
Java, VB, Objective-C come to mind.

--
Greg

Gregory Ewing

unread,
May 1, 2011, 6:37:17 PM5/1/11
to
Terry Reedy wrote:

> While Guido does not, that I know of, credit CLU as Python's direct
> inspiration, I think it (and Barbara Liskov) as the originator of
> Python's data model. I believe she thought of the call-by-object
> semantics as something of an innovation.

I don't think she can claim credit for that, seeing as as Lisp
was built around it. She may have invented the *term* "call by
object" (unnecessarily, in my opinion) but the idea wasn't new.

--
Greg

Terry Reedy

unread,
May 1, 2011, 9:42:45 PM5/1/11
to pytho...@python.org
On 5/1/2011 6:33 PM, Gregory Ewing wrote:
> Steven D'Aprano wrote:
>
>> Python uses a data model of "name binding" and "call by object" (also
>> known as "call by sharing").
>
> It can be summed up in a less jargony way by saying that all
> data is stored in heap-allocated objects,

This is incomprehensible jargon to some; is only (partly) true of
(typical) machine-implementations; and seems not to be true of all
objects. I believe that for CPython, builtin objects, including the
fixed arrray of ints from -5 to 256, are allocated in another data
segment (more CS jargon, which is irrelavant to human interpreters).

Evidence 1:
>>> id(int)
505285072
>>> id(str)
505233232
>>> id(1)
505493792
>>> id(-5)
505493696

This appears to be initialized data segment. (Someone else could take a
white box approach and look at the source. ;-)

>>> id(333333)
16512288
>>> id('a')
11227616

This is heap.

Evidence 2:
Some error messages use 'heap type' to mean 'Python-coded class'

>>> 1 .__class__ = str
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
1 .__class__ = str
TypeError: __class__ assignment: only for heap types

http://bugs.python.org/issue4600

> and variables refer to objects rather than containing them directly.
> Everything else follows from that.

Would you say 'names refer to objects rather than containing them
directly'? Surely not. Using 'name' rather than the hugely overloaded
tern 'variable' automatically avoids certain misunderstandings.

A good summary might be "Python manipulates objects that are accessed
through literals, names, and expressions."
--
Terry Jan Reedy

Message has been deleted

Jorgen Grahn

unread,
May 2, 2011, 3:45:20 AM5/2/11
to
On Sun, 2011-05-01, Terry Reedy wrote:
> On 5/1/2011 4:45 AM, Steven D'Aprano wrote:
...

>> What other languages use the same, or mostly similar, data model as
>> Python?
>
> Natural languages. That is why I think it is better to think of Python
> as an algorithm language or information-object manipulation language
> rather than as just a linear-memory machine language.A linear memory
> with bytes addressed from 0 to max-int or max-long is an explicit part
> of the definition of assembly languages and C. It is no part of the
> definition of Python.

It's not part of the definition of C either -- C supports segmented
memory (pre-386 Intel) and separate code/data address spaces. (Even if
most C users tend not to think of it that way.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Duncan Booth

unread,
May 2, 2011, 4:43:47 AM5/2/11
to
Dennis Lee Bieber <wlf...@ix.netcom.com> wrote:

> As I recall from my programming language design class (only and
> intro, it was so small we met in a meeting room rather than classroom),
> ALGOL was described as "call by name";

It is true that Algol had 'call by name', but (at least the Algol-W that I
learned) also supported 'call by value' and 'call by reference'. The danger
of course was that call by name was the default mechanism so you could end
up using it accidentally.

I remember we had one class where we had to work out (by hand) the output
of a program which used call by name to alias I and A[I] in some recursive
calls. Not nice. Fortunately even at that time it was mostly being taught
as an oddity; real programming was of course done in Algol 68C or BCPL.

--
Duncan Booth http://kupuguy.blogspot.com

Grant Edwards

unread,
May 2, 2011, 9:12:45 AM5/2/11
to

Indeed. All the C compilers I used for many years (on both PDP-11 and
80286 under Unix) assumed a segmented memory space with separate data
and text addresses spaces. More recently, the same can be said for
AVR and many other Harvard architecture machines.

The "linear memory with bytes addressed from 0 to max-int or max-long"
thing is merely an implicit assumption made by bad C programmers.

--
Grant

Hans Georg Schaathun

unread,
May 3, 2011, 8:39:24 AM5/3/11
to
On 01 May 2011 08:45:51 GMT, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
: Python uses a data model of "name binding" and "call by object" (also
: known as "call by sharing"). I trust I don't need to define my terms, but
: just in case:

Without having the time to get my hand around exactly what this means:
Simula has three ways of transmitting arguments, namely transmission
by name, by value, and by reference. Is transmission by name the same
as call by object? Anyway, I have never seen anyone counting more than
three ways of doing this ...


--
:-- Hans Georg

Hrvoje Niksic

unread,
May 3, 2011, 9:50:55 AM5/3/11
to
Steven D'Aprano <steve+comp....@pearwood.info> writes:

> "Python's data model is different from other languages"
>
> which is perfectly correct, if you think of C as "other languages". But
> it's equally correct to say that Python's data model is the same as other
> languages. As I understand it, Python and Ruby have the same data model.

> So does Java, so long as you only consider objects[...]


> What other languages use the same, or mostly similar, data model as
> Python?

Count in Common Lisp and Scheme.

I would say that, considering currently most popular languages and
platforms, Python's data model is in the majority. It is only the
people coming from a C++ background that tend to be confused by it.

Grant Edwards

unread,
May 3, 2011, 10:49:04 AM5/3/11
to
On 2011-05-03, Hans Georg Schaathun <h...@schaathun.net> wrote:
> On 01 May 2011 08:45:51 GMT, Steven D'Aprano
> <steve+comp....@pearwood.info> wrote:
>: Python uses a data model of "name binding" and "call by object" (also
>: known as "call by sharing"). I trust I don't need to define my terms, but
>: just in case:
>
> Without having the time to get my hand around exactly what this means:
> Simula has three ways of transmitting arguments, namely transmission
> by name, by value, and by reference. Is transmission by name the same
> as call by object?

No. For example, assume the argument is a[i].

In call by object, the expression a[i] is evaluated (i is evaluated,
and then used as an index to determine the object that is the ith
element of a). The callee's argument name is then bound to that
object.

In call by name, every time the callee references the argument name,
the expression a[i] is evaluated anew. If the value of 'i' or the
binding of 'a' has changed since the time of the function call, then
the callee's argument now refers to a different object than it did at
the time of the the function call. It's rather like a macro language
(e.g. cpp) which merely performs a textual substitution of the
argument name (the difference between pass-by-name and macro
substitution is that the context of the argument evaluation is
different).

--
Grant Edwards grant.b.edwards Yow! Well, I'm INVISIBLE
at AGAIN ... I might as well
gmail.com pay a visit to the LADIES
ROOM ...

Steven D'Aprano

unread,
May 3, 2011, 11:20:42 AM5/3/11
to

You get credit for not falling into the trap of thinking there are only
two, call by reference and call by value, but there are *many* more than
just three. Wikipedia lists at least 13:

http://en.wikipedia.org/wiki/Evaluation_strategy


See also: http://effbot.org/zone/call-by-object.htm

--
Steven

Mel

unread,
May 3, 2011, 12:33:15 PM5/3/11
to
Hans Georg Schaathun wrote:

To illustrate the neither-fish-nor-fowl nature of Python calls:

mwilson@tecumseth:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def identify_call (a_list):
... a_list[0] = "If you can see this, you don't have call-by-value"
... a_list = ["If you can see this, you have call-by-reference"]
...
>>> my_list = [None]
>>> identify_call (my_list)
>>> my_list
["If you can see this, you don't have call-by-value"]

so it's neither call-by-value nor call-by-reference as (e.g.) C or PL/I
programming would have it (don't know about Simula, so I am off topic,
actually.) It's not so wrong to think of Python's parameter handling as
ordinary assignments from outer namespaces to an inner namespace.

Mel.

Grant Edwards

unread,
May 3, 2011, 12:52:26 PM5/3/11
to
On 2011-05-03, Mel <mwi...@the-wire.com> wrote:

> To illustrate the neither-fish-nor-fowl nature of Python calls:
>
> mwilson@tecumseth:~$ python
> Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
> [GCC 4.4.3] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> def identify_call (a_list):
> ... a_list[0] = "If you can see this, you don't have call-by-value"
> ... a_list = ["If you can see this, you have call-by-reference"]
> ...
>>>> my_list = [None]
>>>> identify_call (my_list)
>>>> my_list
> ["If you can see this, you don't have call-by-value"]
>
> so it's neither call-by-value nor call-by-reference as (e.g.) C or PL/I
> programming would have it (don't know about Simula, so I am off topic,
> actually.) It's not so wrong to think of Python's parameter handling as
> ordinary assignments from outer namespaces to an inner namespace.

As long as you think of "ordinary assignments" the Python way and not
the C or PL/I way. :)

--
Grant Edwards grant.b.edwards Yow! So this is what it
at feels like to be potato
gmail.com salad

Hans Georg Schaathun

unread,
May 3, 2011, 4:47:04 PM5/3/11
to
On Tue, 03 May 2011 12:33:15 -0400, Mel
<mwi...@the-wire.com> wrote:
: mwilson@tecumseth:~$ python

: Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
: [GCC 4.4.3] on linux2
: Type "help", "copyright", "credits" or "license" for more information.
: >>> def identify_call (a_list):
: ... a_list[0] = "If you can see this, you don't have call-by-value"
: ... a_list = ["If you can see this, you have call-by-reference"]
: ...
: >>> my_list = [None]
: >>> identify_call (my_list)
: >>> my_list
: ["If you can see this, you don't have call-by-value"]

This looks like plain old transmission by reference to me.
I.e. the functions get a reference to an object and make any
change to the object. Since the caller and the callee refer
to the same object, changes made by the callee are seen by
the caller. However, the reference cannot be changed.

With transmission by name, you would get what you call
call-by-reference; i.e. the variable passed as an argument is
changed to refer to a completely new object. In simula this
is used for output parameters.

And transmission by value is of course a copy of the data.

: so it's neither call-by-value nor call-by-reference as (e.g.) C or PL/I

I don't know PL/I; that's the sort of thing my mother deals with.
Simula explicitely offerts all three. In C you can get each of the
three, by using pointers explicitely in different ways.

Whether you use C or Simula, transmission by reference, that is what
python appears to be doing, seems to be the normal approach for any
composite data type. Thus python does not seem to do anything out of
the ordinary at all.

--
:-- Hans Georg

Hans Georg Schaathun

unread,
May 3, 2011, 5:10:52 PM5/3/11
to
On 03 May 2011 15:20:42 GMT, Steven D'Aprano
<steve+comp....@pearwood.info> wrote:
: You get credit for not falling into the trap of thinking there are only
: two, call by reference and call by value, but there are *many* more than
: just three. Wikipedia lists at least 13:

Ah. Those 13 approaches aren't all mutually exclusive though.

--
:-- Hans Georg

Chris Angelico

unread,
May 3, 2011, 6:00:35 PM5/3/11
to pytho...@python.org
On Wed, May 4, 2011 at 6:47 AM, Hans Georg Schaathun <h...@schaathun.net> wrote:
> This looks like plain old transmission by reference to me.
> I.e. the functions get a reference to an object and make any
> change to the object.

"Reference" being exactly what's passed around. There are now two
references to that object. Since names always contain references (not
objects), it's very easy to share mutable objects
(lists/dictionaries/etc). There's an easy way for a caller or callee
to guarantee that a mutable is safe - just slice it:

identify_call(my_list[:])

That gives the called function a shallow copy of the list, which it
can modify to its heart's content, but the original list isn't
changed. Callee can do the same, with an assignment command at the top
of the function (a_list=a_list[:]).

Chris Angelico

Devin Jeanpierre

unread,
May 4, 2011, 5:56:28 AM5/4/11
to
> To illustrate the neither-fish-nor-fowl nature of Python calls:
>
> mwilson@tecumseth:~$ python
> Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
> [GCC 4.4.3] on linux2
> Type "help", "copyright", "credits" or "license" for more information.>>> def identify_call (a_list):
>
> ...   a_list[0] = "If you can see this, you don't have call-by-value"
> ...   a_list = ["If you can see this, you have call-by-reference"]
> ...>>> my_list = [None]
> >>> identify_call (my_list)
> >>> my_list
>
> ["If you can see this, you don't have call-by-value"]
>
> so it's neither call-by-value nor call-by-reference as (e.g.) C or PL/I
> programming would have it (don't know about Simula, so I am off topic,
> actually.)  It's not so wrong to think of Python's parameter handling as
> ordinary assignments from outer namespaces to an inner namespace.
>
>         Mel.

Eh, that example doesn't say what you think it does. It has the same
behavior in C: http://ideone.com/Fq09N . Python is pass-by-value in a
meaningful sense, it's just that by saying that we say that the values
being passed are references/pointers. This is maybe one level of
abstraction below what's ideal, but Scheme, Java, etc. share this
terminology. (Ruby calls it pass-by-reference AFAIK. Whatever, a rose
by any other name...)

Devin Jeanpierre

Steven D'Aprano

unread,
May 4, 2011, 6:51:33 AM5/4/11
to
On Wed, 04 May 2011 02:56:28 -0700, Devin Jeanpierre wrote:

> Python is pass-by-value in a
> meaningful sense, it's just that by saying that we say that the values
> being passed are references/pointers. This is maybe one level of
> abstraction below what's ideal,

"Maybe"?

Given the following statement of Python code:

>>> x = "spam"

what is the value of the variable x? Is it...?

(1) The string "spam".

(2) Some invisible, inaccessible, unknown data structure deep in the
implementation of the Python virtual machine, which the coder cannot
access in any way using pure Python code.

(Possibly a pointer, but since it's an implementation detail, other
implementations may make different choices.)

(3) Something else.


I argue that any answer except for (1) is (almost always) counter-
productive: it adds more confusion than shedding light. It requires
thinking at the wrong level, at the implementation level instead of the
level of Python code. If we define "value" to mean the invisible,
inaccessible reference, then that leaves no word to describe was the
string "spam" is.

(I say "almost always" counter-productive because abstractions leak, and
sometimes you do need to think about implementation.)


> but Scheme, Java, etc. share this
> terminology. (Ruby calls it pass-by-reference AFAIK.

The intellectual contortions that some people will go through to hammer
the square peg of actual programming language behaviour into the two
round holes of "pass by value" and "pass by reference" never cease to
astonish me.


> Whatever, a rose by any other name...)

Do you really think that roses would be the symbol of romantic love if
they were called "disgusting stink-weeds of perversion and death"?

"How was the date last night?"
"Oh, it was marvelous! He presented me with a single red stink-weed, and
then we went to a disgusting little restaurant. I had the swill."

When people cannot agree on the definition of words, how can they
communicate? Pass by reference Ruby is completely different from the
older usage in Pascal, VB and other languages. Likewise, pass by value in
Java is completely different from that in older languages. Pass by
reference in Ruby, and pass by value in Java, describe the same thing.
What were these people thinking?


--
Steven

Paul Rubin

unread,
May 4, 2011, 6:58:51 AM5/4/11
to
Steven D'Aprano <steve+comp....@pearwood.info> writes:
>>>> x = "spam"
> what is the value of the variable x? Is it...?
> (1) The string "spam".

Python works about the same way as Lisp or Scheme with regard to this
sort of thing, and those languages have been described with quite a bit
of mathematical formality. So if you want a precise theoretical
treatment you might look at the Scheme report. It should be pretty
clear how it carries over to Python.

Hans Georg Schaathun

unread,
May 4, 2011, 6:56:16 AM5/4/11
to
On Wed, 4 May 2011 02:56:28 -0700 (PDT), Devin Jeanpierre
<jeanpi...@gmail.com> wrote:
: Eh, that example doesn't say what you think it does. It has the same

: behavior in C: http://ideone.com/Fq09N . Python is pass-by-value in a
: meaningful sense, it's just that by saying that we say that the values
: being passed are references/pointers.

No, Python is not pass-by-value, because the pointer is abstracted
away. You transmit arguments by reference only and cannot access the
value of the reference. In C it is pass by value, as the pointer
is explicit and do whatever you want with the pointer value.

So, even though you have the same mechanism in C and Python, they
do not have the same name. In the low-level C you only have pass
by value, but you can use the pointer syntax to do whatever you want
within pass by value. In the higher-level python, you do not have
the flexibility provided by explicit pointers, so you need to explain
the semantics without having a pointer concept defined a priori.

: This is maybe one level of


: abstraction below what's ideal, but Scheme, Java, etc. share this
: terminology. (Ruby calls it pass-by-reference AFAIK. Whatever, a rose
: by any other name...)

Now, this is confusing, because the terminology is not universal and
hardly intuitive. What is called transmission by reference in a
Simula context (Bjørn Kirkerud's textbook on OO Programming with Simula
for instance) is called object sharing in Wikipedia. What Wikipedia
calls call by reference is transmission by name in the Simula context.

--
:-- Hans Georg

Devin Jeanpierre

unread,
May 4, 2011, 9:12:14 AM5/4/11
to
On May 4, 6:51 am, Steven D'Aprano <steve

+comp.lang.pyt...@pearwood.info> wrote:
> On Wed, 04 May 2011 02:56:28 -0700, Devin Jeanpierre wrote:
> > Python is pass-by-value in a
> > meaningful sense, it's just that by saying that we say that the values
> > being passed are references/pointers. This is maybe one level of
> > abstraction below what's ideal,
>
> "Maybe"?
>
> Given the following statement of Python code:
>
> >>> x = "spam"
>
> what is the value of the variable x? Is it...?
>
> (1) The string "spam".
>
> (2) Some invisible, inaccessible, unknowndatastructure deep in the

> implementation of the Python virtual machine, which the coder cannot
> access in any way using pure Python code.
>
> (Possibly a pointer, but since it's an implementation detail, other
> implementations may make different choices.)
>
> (3) Something else.

As I said, a pointer or reference.

> I argue that any answer except for (1) is (almost always) counter-
> productive: it adds more confusion than shedding light. It requires
> thinking at the wrong level, at the implementation level instead of the
> level of Python code. If we define "value" to mean the invisible,
> inaccessible reference, then that leaves no word to describe was the
> string "spam" is.
>
> (I say "almost always" counter-productive because abstractions leak, and
> sometimes you do need to think about implementation.)

I don't know why you want to argue that it's counter-productive when
all I said was that it was meaningful / worked.

I don't think of "pass-by-value" involving references as being an
implementation-level thing. It's a way of thinking about Python's
behavior: a model. There don't even need to be actual references or
anything resembling them inside the implementation in order to apply
the model (for example, we probably all accept that Python could be
implemented using a turing machine, which lacks references/pointers).

Also, the word you suspected did not exist is "object". So if we have
var = "spam", var is a variable containing a reference to the object
"spam". Alternatively, it's a handle for the object "spam". I think
that's the call-by-sharing terminology, anyway.

> > but Scheme, Java, etc. share this
> > terminology. (Ruby calls it pass-by-reference AFAIK.
>
> The intellectual contortions that some people will go through to hammer
> the square peg of actual programming language behaviour into the two
> round holes of "pass by value" and "pass by reference" never cease to
> astonish me.

It isn't particularly contorted. I learned Python this way and it
makes perfect sense. It's just perhaps one level of abstraction away
from the ideal of what some programmers would think in. Python's "pass-
by-value" conforms exactly to the "pass-by-value" of other languages
such as C. The only twist is that you never get to dereference
pointers in Python, but you can in C. Not much of a twist if you ask
me, but then again, I've been thinking in this model for years. Maybe
I'm brainwashed. :)

> > Whatever, a rose by any other name...)
>
> Do you really think that roses would be the symbol of romantic love if
> they were called "disgusting stink-weeds of perversion and death"?
>
> "How was the date last night?"
> "Oh, it was marvelous! He presented me with a single red stink-weed, and
> then we went to a disgusting little restaurant. I had the swill."

Please don't argue with me in this manner. The point is that words
don't matter, the meaning behind them does. As long as it's clear
what's meant, and what's meant is internally-consistent, I don't have
much problem with it. Of course, this is a rule of thumb and you could
draw extreme scenarios where it just becomes a bother.

Devin Jeanpierre

Devin Jeanpierre

unread,
May 4, 2011, 9:13:48 AM5/4/11
to
On May 4, 6:56 am, Hans Georg Schaathun <h...@schaathun.net> wrote:

> On Wed, 4 May 2011 02:56:28 -0700 (PDT), Devin Jeanpierre  <jeanpierr...@gmail.com> wrote:
>
> :  Eh, that example doesn't say what you think it does. It has the same
> :  behavior in C:http://ideone.com/Fq09N. Python is pass-by-value in a

> :  meaningful sense, it's just that by saying that we say that the values
> :  being passed are references/pointers.
>
> No, Python is not pass-by-value, because the pointer is abstracted
> away.  You transmit arguments by reference only and cannot access the
> value of the reference.  In C it is pass by value, as the pointer
> is explicit and do whatever you want with the pointer value.  

The same argument applies to every language I know but two, all of
which describe themselves as pass-by-value. What you say certainly has
a consistency to it, it's just at odds with how I generally see the
term being applied. Forgive me if I don't share the same definition as
you, even if I do appreciate its elegance.

Devin Jeanpierre

Hans Georg Schaathun

unread,
May 4, 2011, 9:44:07 AM5/4/11
to
On Wed, 4 May 2011 06:12:14 -0700 (PDT), Devin Jeanpierre
<jeanpi...@gmail.com> wrote:
: I don't think of "pass-by-value" involving references as being an

: implementation-level thing. It's a way of thinking about Python's
: behavior: a model. (...)
: It isn't particularly contorted. I learned Python this way and it

: makes perfect sense. It's just perhaps one level of abstraction away
: from the ideal of what some programmers would think in. Python's "pass-
: by-value" conforms exactly to the "pass-by-value" of other languages
: such as C.

It is contorted and implementation-level because it is one level below
the abstraction assumed by the language. It only works by assuming
knowledge of C, which is language which has proved unsuitable for
complex and abstract data modelling. Digging down into C should be
unnecessary to explain Python.

By calling it pass-by-value you introduce a new data type which is
unknown to Python, namely the pointer.

: The only twist is that you never get to dereference


: pointers in Python, but you can in C. Not much of a twist if you ask
: me, but then again, I've been thinking in this model for years. Maybe
: I'm brainwashed. :)

You are. You explain Python in terms of C. That's useful when you
talk to other speakers of C.

If you want to explain the language to a broader audience, you should
use terminology from the language's own level of abstraction.


--
:-- Hans Georg

Chris Angelico

unread,
May 4, 2011, 10:20:34 AM5/4/11
to pytho...@python.org
On Wed, May 4, 2011 at 11:44 PM, Hans Georg Schaathun <h...@schaathun.net> wrote:
> It is contorted and implementation-level because it is one level below
> the abstraction assumed by the language.  It only works by assuming
> knowledge of C, which is language which has proved unsuitable for
> complex and abstract data modelling.  Digging down into C should be
> unnecessary to explain Python.

Sometimes, to explain Python, you need to dig down to the underlying
hardware - even deeper than C, if you like. And that's always going to
be the way, because abstractions leak from time to time. Or I should
say, they occasionally have confidential briefings with the press.
Abstracting everything perfectly is neither possible nor desirable.

Chris Angelico

sturlamolden

unread,
May 4, 2011, 10:28:16 AM5/4/11
to
On May 3, 3:50 pm, Hrvoje Niksic <hnik...@xemacs.org> wrote:

> I would say that, considering currently most popular languages and
> platforms, Python's data model is in the majority.  It is only the
> people coming from a C++ background that tend to be confused by it.

In C++, one will ususally put class variables (objects) on the stack
or in STL containers, and use references instead of pointers. This way
one gets deterministic clean-up, and operator overloading will work as
expected. It is a common beginner mistake for people coming from Java
to use "new" anywhere in C++ code, instead of inside constructors
only. Used properly, C++ has a data model for class variables similar
to Fortran (pass-by-reference). This is complicated by the ability of C
++ to pass-by-value for backwards compatibility with C, inclusing the
use of raw pointers. This hybrid and convoluted data model of C++ is a
common source of confusion and programming mistakes, both for
programmers coming from C++ to Python or C# or vice versa.

Java is somewhat between C and C#, in that it has C semantics for
elementary types (e.g. int and float), but not for objects in general.
In C# and Python, elementary types are immutable objects, byut thet
have no special pass-by-value semantics.

Python has the same data model as Scheme. This includes that code is
an object in Python (in Python that is byte code not source code, thus
no Lisp macros). Variables are names that bind to an object. Objects
are passed as references, but names are not. "Dummy arguments" (to use
Fortran termininology) are bound to the same objects with which the
function was called, but this is not call-by-reference semantics in
the style of Fortran and C++:

In Python, the "=" operator will rebind in the local scope, as in C,
Java and C#. It will not affect anything the the calling scope (as in C
++ and Fortran). Nevertheless, this is not pass-by-value, as no copy
are made. A reference in C++ and Fortran is an alias for the variable
in the calling scope. In Python it is a new variable pointing to the
same value. This is a major difference, but a common source of error
for those that don't understand it.

( for those confused about the claimed behavior of "=" in C++: The
previous paragraph deals with reference variables in C++, not those
passed with C-style pass-by-value sematics. C++ does not always behave
as C, sometimes it behaves like Fortran and Pascal.)

Thus, Python does not pass-by-value like C or C++, nor does it pass-by-
reference like C++ or Fortran.

The semantics of Python, C# and Lisp might be described as "pass-by-
handle" if we need to put a name on it.


sturlamolden

unread,
May 4, 2011, 10:44:38 AM5/4/11
to
On May 3, 6:33 pm, Mel <mwil...@the-wire.com> wrote:

> def identify_call (a_list):


> a_list[0] = "If you can see this, you don't have call-by-value"

> a_list = ["If you can see this, you have call-by-reference"]


The first one is a mistake. If it were pass-by-value, it would
assign the string to a list unseen by the caller -- i.e. a copy
of the caller's argument (same value, different object).

But that does not happen. The string is assigned to the list
seen by the caller. Thus we can exclude call-by-value.

The second proposition is correct. This allows us to exclude
pass-by-reference similar to C++, Pascal and Fortran.

Thus:

def identify_call (a_list):
a_list[0] = "If you cannot see this, you have call-by-value"


a_list = ["If you can see this, you have call-by-reference"]


Clearly Python has neither call-by-value nor call-by-reference.

Python uses a third mechanism.

Sturla


Michael Torrie

unread,
May 4, 2011, 11:40:02 AM5/4/11
to pytho...@python.org
On 05/04/2011 08:44 AM, sturlamolden wrote:
> On May 3, 6:33 pm, Mel <mwil...@the-wire.com> wrote:
>
>> def identify_call (a_list):
>> a_list[0] = "If you can see this, you don't have call-by-value"
>> a_list = ["If you can see this, you have call-by-reference"]
>
>
> The first one is a mistake. If it were pass-by-value, it would
> assign the string to a list unseen by the caller -- i.e. a copy
> of the caller's argument (same value, different object).
> <snip>

> Clearly Python has neither call-by-value nor call-by-reference.
>
> Python uses a third mechanism.

Which is exactly what the code showed. The first one isn't a mistake.
You just read it wrong.

Devin Jeanpierre

unread,
May 4, 2011, 12:18:56 PM5/4/11
to
On May 4, 9:44 am, Hans Georg Schaathun <h...@schaathun.net> wrote:
> : The only twist is that you never get to dereference
> : pointers in Python, but you can in C. Not much of a twist if you ask
> : me, but then again, I've been thinking in thismodelfor years. Maybe

> : I'm brainwashed. :)
>
> You are. You explain Python in terms of C. That's useful when you
> talk to other speakers of C.
>
> If you want to explain the language to a broader audience, you should
> use terminology from the language's own level of abstraction.

No, I explained Python in terms of pointers/reference. I don't speak C
or come from a C background, I'm primarily a Python programmer. Also,
I don't agree with your notions of "should", I have seen it taught
this way to plenty of undergraduate students learning Python as their
first programming language, and they do fine. The precise notational
difference between sharing an object and copying a reference doesn't
matter, as long as you can draw a diagram of it and write/read code --
which they can, and they do fine.

I'm a bit uncomfortable with the vibe here. It's one thing for me to
self-deprecatingly suggest I'm brainwashed (with a smile), and another
for you to agree in complete seriousness.

Devin Jeanpierre

sturlamolden

unread,
May 4, 2011, 12:40:12 PM5/4/11
to
On May 4, 5:40 pm, Michael Torrie <torr...@gmail.com> wrote:

> Which is exactly what the code showed.  The first one isn't a mistake.
> You just read it wrong.

No, I read "call-by-value" but it does not make a copy. Call-by-value
dictates a deep copy or copy-on-write. Python does neither. Python
pass a handle to the object, not a handle to a copy of the object. If
you want to see call-by-value in practice, take a look at MATLAB,
SciLab or Octave; or consider what C++ copy constructors do in
function calls with value types.

The first one is indeed a mistake. An object has a value. A name binds
to an object, not to a value. If Python did pass-by-value, the string
would be inserted in an object (here: a list) with the same value
(e.g. empty list), it would not modify the same object by which you
called the function.

I think you understand what Python does, but not what call-by-value
would do.


C++ tells you the difference:


// copy constructor is invoked
// x is a copy of the argument's value
// this is call-by-value

void foobar1(Object x);


// no copy is taken
// x is a logical alias of the argument
// this is call-by-reference

void foobar2(Object &x);


// x is a pointer, not an object
// x is a copy of another pointer
// this is similar to Python sematics
// the pointer is passed by value, not the pointee

// in C, this is sometimes called call-by-reference
// as there are no reference types, but it's not

void foobar3(Object *x);

Sturla


Hans Georg Schaathun

unread,
May 4, 2011, 1:03:05 PM5/4/11
to
On Wed, 4 May 2011 09:18:56 -0700 (PDT), Devin Jeanpierre
<jeanpi...@gmail.com> wrote:
: I'm a bit uncomfortable with the vibe here. It's one thing for me to

: self-deprecatingly suggest I'm brainwashed (with a smile), and another
: for you to agree in complete seriousness.

I am sorry. It was not meant to be an insult. I do think that you
sit tightly in a frame of reference which is obviously not the only
one appropriate, and IMNHO not the optimal one for the purpose.
"Brainwashed" was not a word I meant to take seriously. Apologies.

I should have cut the C reference too; the same frame of reference
could be adopted from any number of languages.

Note that it was not the use of references as a concept I objected to,
but that they might be passed by value. With the references being
purely abstract entities and not data objects, the idea that they
have values do not make sense. And pass-by-value where the value
is a reference is just confusing.

--
:-- Hans Georg

Hans Georg Schaathun

unread,
May 4, 2011, 1:09:56 PM5/4/11
to
On Thu, 5 May 2011 00:20:34 +1000, Chris Angelico
<ros...@gmail.com> wrote:
: Sometimes, to explain Python, you need to dig down to the underlying

: hardware - even deeper than C, if you like.

Sometimes you may need to narrow down the scope and explain a particular
implementation of python with its hardware, OS, and interpreter.
However, explaining just python, you do not know what the underlying
hardware/OS/interpreter is, and digging down into it is not possible.

: And that's always going to


: be the way, because abstractions leak from time to time. Or I should
: say, they occasionally have confidential briefings with the press.
: Abstracting everything perfectly is neither possible nor desirable.

Sure, but every language assumes a certain level of abstraction, and
when the abstraction breaks the language fails to be unambiguous and/or
portable.

--
:-- Hans Georg

Benjamin Kaplan

unread,
May 4, 2011, 1:15:43 PM5/4/11
to pytho...@python.org
On Wed, May 4, 2011 at 12:40 PM, sturlamolden <stu...@molden.no> wrote:
>
> On May 4, 5:40 pm, Michael Torrie <torr...@gmail.com> wrote:
>
> > Which is exactly what the code showed.  The first one isn't a mistake.
> > You just read it wrong.
>
> No, I read "call-by-value" but it does not make a copy. Call-by-value
> dictates a deep copy or copy-on-write. Python does neither. Python
> pass a handle to the object, not a handle to a copy of the object. If
> you want to see call-by-value in practice, take a look at MATLAB,
> SciLab or Octave; or consider what C++ copy constructors do in
> function calls with value types.

You missed a word in the sentence.

"If you can see this, you DON'T have call-by-value"

sturlamolden

unread,
May 4, 2011, 1:19:50 PM5/4/11
to
On May 4, 7:15 pm, Benjamin Kaplan <benjamin.kap...@case.edu> wrote:

> You missed a word in the sentence.
>
> "If you can see this, you DON'T have call-by-value"

Indeed I did, sorry!

Then we agree :)


Sturla

harrismh777

unread,
May 4, 2011, 3:22:38 PM5/4/11
to
Hans Georg Schaathun wrote:
> It only works by assuming
> knowledge of C, which is language which has proved unsuitable for
> complex and abstract data modelling.

That statement is untrue; evidenced by the very fact the CPython's
complex and abstract data modeling has been very suitably handled by C.
You cannot possibly mean what you have asserted... I realize there
must be a contextual problem. I have been handling complex data
abstractions with C for more than 20 years... its quite well suited to
the task... although, I am able to do my research today faster and with
less lines of code in CPython. That does not in any way impugn C..;.
quite the contrary, given enough time, C is better suited for modeling
on a von Neumann processor, period.

Here is the thing that everyone forgets... all we have to work with
is a von Neumann processor. (same as EDVAC, ENIAC, the VIC20, etc).
Assembler is still the best language on that processor. 'C' is still
the best high-level language on that processor. CPython is implemented
in C for a reason: gcc and the von Neumann processor make it a no-brainer.

Its silly to claim that one high-level language or another is better
suited to complex data abstraction... don't go there.


> Digging down into C should be unnecessary to explain Python.


huh? You have to be kidding. Why do you suppose we want it to be
open-sourced? Use the force Luke, read the source. If you really
want to know how Python is working you *must* dig down into the C code
which implements it. The folks who document Python should be able to
tell us enough to know how to use the language, but to really 'know' you
need the implementation source.

kind regards,
m harris

harrismh777

unread,
May 4, 2011, 3:33:34 PM5/4/11
to
Hans Georg Schaathun wrote:
> In C it is pass by value, as the pointer
> is explicit and do whatever you want with the pointer value.

You clearly are not a C programmer.

Most of my C data abstractions use dual circular linked lists of
pointers to structures of pointers. *All* of that is only ever passed
(at least in my programming) as references. My code almost never passes
data by value.

We do not consider passing a pointer as *by value* because its an
address; by definition, that is pass-by-reference. We are not passing
the *value* of the data, we are passing the memory location (the
reference) to the data. Pass by *value* on the other hand actually
places the *value* of the data item on the call stack as a parameter.

Much of this conversation has more to do with semantics.


kind regards,
m harris


Benjamin Kaplan

unread,
May 4, 2011, 3:46:07 PM5/4/11
to pytho...@python.org
On Wed, May 4, 2011 at 3:22 PM, harrismh777 <harri...@charter.net> wrote:
> Hans Georg Schaathun wrote:
>>
>> It only works by assuming
>> knowledge of C, which is language which has proved unsuitable for
>> complex and abstract data modelling.
>
>   That statement is untrue; evidenced by the very fact the CPython's complex
> and abstract data modeling has been very suitably handled by C.
>   You cannot possibly mean what you have asserted... I realize there must be
> a contextual problem.  I have been handling complex data abstractions with C
> for more than 20 years... its quite well suited to the task... although, I
> am able to do my research today faster and with less lines of code in
> CPython.  That does not in any way impugn C..;. quite the contrary, given
> enough time,  C is better suited for modeling on a von Neumann processor,
> period.
>
>   Here is the thing that everyone forgets... all we have to work with is a
> von Neumann processor. (same as EDVAC, ENIAC, the VIC20, etc). Assembler is
> still the best language on that processor.  'C'  is still the best
> high-level language on that processor.  CPython is implemented in C for a
> reason:  gcc and the von Neumann processor make it a no-brainer.
>

CPython is implemented in C because that's the language chosen. Python
is also implemented in Java, C#, Python, and several other languages.
And it's not tied to the von Neumann architecture either. Only the
current implementations of it are.

>   Its silly to claim that one high-level language or another is better
> suited to complex data abstraction... don't go there.
>
>
>> Digging down into C should be unnecessary to explain Python.
>
>
>   huh?   You have to be kidding. Why do you suppose we want it to be
> open-sourced?   Use the force Luke, read the source.   If you really want to
> know how Python is working you *must* dig down into the C code which
> implements it.  The folks who document Python should be able to tell us
> enough to know how to use the language, but to really 'know' you need the
> implementation source.
>

Reading the CPython sources will show you how CPython works under the
hood, but it has nothing to do with how Python works. There are lots
of things that CPython does that "Python" does not. For instance, the
GIL is not a part of Python. Reference counting is not a part of
Python. Caching small integers and strings is not a part of Python.
Why not read the Jython sources instead of the CPython? It's the same
language, after all.

harrismh777

unread,
May 4, 2011, 3:47:35 PM5/4/11
to
Devin Jeanpierre wrote:
>> "How was the date last night?"

>> > "Oh, it was marvelous! He presented me with a single red stink-weed, and
>> > then we went to a disgusting little restaurant. I had the swill."

> Please don't argue with me in this manner.

D'Aprano takes a little getting used to. He likes strawmen,
red-hearings, and the venerable bogus analogy. Just read around them, he
usually has some good points in there...


kind regards,
m harris

harrismh777

unread,
May 4, 2011, 3:58:38 PM5/4/11
to
Benjamin Kaplan wrote:
> CPython is implemented in C because that's the language chosen. Python
> is also implemented in Java, C#, Python, and several other languages.

True enough. If I used Jython, I would want to take a look at those
sources... as well as the Java sources... which were wrtten in, um, C.

> And it's not tied to the von Neumann architecture either. Only the
> current implementations of it are.

Oh, yes they are. That is the $10,000,000 dollar problem... how to
extricate ourselves from the von Neumann processor. *Everthing* comes
down to that... its hilarious to hear folks talk about lambda the
ultimate (especially those guys on Lambda the Ultimate) when there is no
such thing until such time as we have lambda the hardware architecture.
As long as we are all constrained to funnel data through the von
Neumann ALU, that really is *all* that matters. Another way of saying
this is that no matter how sophisticated our high level coding gets, it
all has to be translated somehow one way or another into von Neumann
codes toggling 1's and 0's on and off in the registers of the von
Neumann ALU.


> Reading the CPython sources will show you how CPython works under the
> hood, but it has nothing to do with how Python works.

Not conceptually, but practically. For instance, for a C programmer
to see that Python's object references are C void pointers, tells the
newbie Python ( C programmer ) much about how Python considers
variables... as references... to objects.

> There are lots
> of things that CPython does that "Python" does not. For instance, the
> GIL is not a part of Python. Reference counting is not a part of
> Python. Caching small integers and strings is not a part of Python.

This is not something I was aware of... caching of small ints is
unique to CPython implementation only ?? I guess I'll have to go read
the "sources" of the other implementations to check that out... ;-)

> Why not read the Jython sources instead of the CPython? It's the same
> language, after all.

Yep. Agreed. .... on both counts.


Hans Georg Schaathun

unread,
May 4, 2011, 3:58:01 PM5/4/11
to
On Wed, 04 May 2011 14:22:38 -0500, harrismh777
<harri...@charter.net> wrote:
: That statement is untrue; evidenced by the very fact the CPython's
: complex and abstract data modeling has been very suitably handled by C.

That's an implementation. Not modelling.

: You cannot possibly mean what you have asserted... I realize there

: must be a contextual problem. I have been handling complex data
: abstractions with C for more than 20 years...

I did not say that it is impossible. On the other hand, you are
clearly not talking about abstraction or modelling at all, but
rather about computation or data processing.

: its quite well suited to

: the task... although, I am able to do my research today faster and with
: less lines of code in CPython. That does not in any way impugn C..;.
: quite the contrary, given enough time, C is better suited for modeling
: on a von Neumann processor, period.

What has that got to do with abstraction?

: Here is the thing that everyone forgets... all we have to work with

: is a von Neumann processor. (same as EDVAC, ENIAC, the VIC20, etc).
: Assembler is still the best language on that processor. 'C' is still
: the best high-level language on that processor. CPython is implemented
: in C for a reason: gcc and the von Neumann processor make it a no-brainer.

Again, what has that got to do with abstraction?

: Its silly to claim that one high-level language or another is better

: suited to complex data abstraction... don't go there.

:
: > Digging down into C should be unnecessary to explain Python.
:
: huh? You have to be kidding. Why do you suppose we want it to be
: open-sourced?

Python is a /language/. The /implementation/ is may be open-source
(and may or may not be written in C).

: Use the force Luke, read the source. If you really

: want to know how Python is working you *must* dig down into the C code
: which implements it.

Except that whatever you learn by doing so is only valid for that one
interpreter.

--
:-- Hans Georg

Grant Edwards

unread,
May 4, 2011, 4:19:05 PM5/4/11
to
On 2011-05-04, harrismh777 <harri...@charter.net> wrote:
> Hans Georg Schaathun wrote:

>> In C it is pass by value, as the pointer is explicit and do whatever
>> you want with the pointer value.
>
> You clearly are not a C programmer.
>
> Most of my C data abstractions use dual circular linked lists of
> pointers to structures of pointers. *All* of that is only ever passed
> (at least in my programming) as references. My code almost never
> passes data by value.
>
> We do not consider passing a pointer as *by value* because its an
> address; by definition, that is pass-by-reference.

No, it isn't. It's pass by value. The fact that you are passing a
value that is a pointer to another value is not relevent.

Pass by reference means that if I call

foo(x)

And foo looks like this:

foo(param)
param = 4

Then 'x' in the caller's namespace ends up set to 4.

> We are not passing the *value* of the data, we are passing the memory
> location (the reference) to the data.

You're pass a value. That value is a pointer to some other value.

> Pass by *value* on the other hand actually places the *value* of the
> data item on the call stack as a parameter.

C is pass by value.

if I call foo(x)

And this is foo:

void foo (float param)
{
param = 1.23
}

The value of x in the caller's namespace is not changed. If C used
pass by reference, x would change.

--
Grant Edwards grant.b.edwards Yow! SHHHH!! I hear SIX
at TATTOOED TRUCK-DRIVERS
gmail.com tossing ENGINE BLOCKS into
empty OIL DRUMS ...

Hans Georg Schaathun

unread,
May 4, 2011, 4:20:54 PM5/4/11
to
On Wed, 04 May 2011 14:33:34 -0500, harrismh777
<harri...@charter.net> wrote:

: Hans Georg Schaathun wrote:
: > In C it is pass by value, as the pointer
: > is explicit and do whatever you want with the pointer value.
:
: You clearly are not a C programmer.

I am not really a programmer period. I am many things and run
into programming from many more angles than a typical programmer
does. And as to C, I no longer use C when I can avoid it (which
I can most but not all of the time).

A few words are missing though. C is semantically pass by value.
Always. But because you have pointers are data object, you can do
whatever you want with them, and pass a pointer by value. Thus you
can achieve the effect of transmission by reference or by name, if
you want to.

: Most of my C data abstractions use dual circular linked lists of

: pointers to structures of pointers. *All* of that is only ever passed
: (at least in my programming) as references. My code almost never passes
: data by value.

Not if you do not consider pointers as data, but C does, in the sense
that pointers can be manipulated in the same ways as any other kind of
data.

: We do not consider passing a pointer as *by value* because its an

: address; by definition, that is pass-by-reference. We are not passing
: the *value* of the data, we are passing the memory location (the
: reference) to the data. Pass by *value* on the other hand actually
: places the *value* of the data item on the call stack as a parameter.

That is a useful viewpoint, but it falls a bit short when you need
to explain how to deal with pointers to pointers to pointers. Pointers
in C are objects.

But mind you, I was not the one to suggested to refer to this
as pass by value. I was explaining why it makes more sense to
do so for C but not for Python.

You simply end up with different wordings if you try to explain how
C works, and how to model data in C. We can both be right, you know;
we are just addressing the issues at different levels of abstraction.

: Much of this conversation has more to do with semantics.

Of course. The concepts are used to explain the semantics of the
languages.

--
:-- Hans Georg

Hans Georg Schaathun

unread,
May 4, 2011, 4:40:43 PM5/4/11
to
On Wed, 04 May 2011 14:58:38 -0500, harrismh777
<harri...@charter.net> wrote:
: True enough. If I used Jython, I would want to take a look at those
: sources... as well as the Java sources... which were wrtten in, um, C.

And then, suddenly, you'll be developing code which fails on CPython
instead of code which fails on Jython. Except that it will still
fail on Jython too, unless you happen to have the right jvm.

Marvelous.

: Oh, yes they are. That is the $10,000,000 dollar problem... how to

: extricate ourselves from the von Neumann processor. *Everthing* comes
: down to that... its hilarious to hear folks talk about lambda the
: ultimate (especially those guys on Lambda the Ultimate) when there is no
: such thing until such time as we have lambda the hardware architecture.

The problem with your approach is that software development does not
scale. Assembly worked very well with a few 100 lines of codes half
a century ago. C and friends were a great step forward and reduced
the complexity to allow another magnitude of lines of codes. Then
came further languages further removed from von Neumann, but close
enough to human cognition to handle yet a magnitude or too.

Of course you can still gain useful understanding by studying assembly
or von Neumann, or the instruction set of the CPU you use. And in
some projects it may be an optimal strategy. However, there are
many skills necessary to make an efficient system and in many projects
assembly and hardware skills are far down the list.

Virtualisation is there to the cut costs of rethinking solutions for
multiple architectures. If you need to understand the implementation
to do your programming, you are in fact disregarding one of the most
significant achievements deployed in computing the last two decades.

: Not conceptually, but practically. For instance, for a C programmer

: to see that Python's object references are C void pointers, tells the
: newbie Python ( C programmer ) much about how Python considers
: variables... as references... to objects.

And of course, this is useful as /one/ way to consider python variables.
As long as one is aware that this is just an example, one approach out
of many, then it enhances understanding. If one blindly extrapolates
from one implementation, it enhances misunderstanding.


--
:-- Hans Georg

harrismh777

unread,
May 4, 2011, 5:35:50 PM5/4/11
to
Grant Edwards wrote:
>> We do not consider passing a pointer as*by value* because its an

>> > address; by definition, that is pass-by-reference.
> No, it isn't. It's pass by value. The fact that you are passing a
> value that is a pointer to another value is not relevent.
>

@ Edwards, &Schaathun

You are most definitely mistaken. See:

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr233.htm


I understand that semantically some people insist that when C receives
parms as pointers that pass-by-reference is only being simulated.

But that is the silliness of this argument... because down in the guts
of the ALU we only have direct and indirect memory addressing. Period.

You either pass a function the memory directly (value) or you pass the
data indirectly (reference).

Everything above that is high-level semantics.


If I want to pass values to my C functions, I can. If I want to pass
references to my C functions, I can.

If I want to implement a C language that does not use pointers directly
(hides them) I can implement pass by reference completely (on the
surface). In fact, I can implement the C compiler so that pass by value
is not allowed! [ it wouldn't look much like C, but its do-able ]


Everyone forgets that their high-level language is not 'really' what's
working... gcc does not produce machine code... it produces assembler
instructions that are passed to a translator... you can interrupt the
process and have it produce the assembly instructions so you can see
them if you want to... the point being, after all is said and done, all
you can do with today's von Neumann processors is pass data directly
(value) or indirectly (reference).

Everything else is semantics.

Ben Finney

unread,
May 4, 2011, 5:43:59 PM5/4/11
to
Steven D'Aprano <steve+comp....@pearwood.info> writes:

> Given the following statement of Python code:
>
> >>> x = "spam"
>
> what is the value of the variable x?

Mu (無).

‘x’ is a name. Names are bound to values. Talk of “variable” only
confuses the issue because of the baggage carried with that term.

Yes, the Python documentation disagrees with me.

> (1) The string "spam".

> I argue that any answer except for (1) is (almost always) counter-


> productive: it adds more confusion than shedding light.

I prefer to respond “The name ‘x’ is bound to a string, "spam"”.

(If I knew which version of Python we're using, I'd qualify the type as
“a text string” or “a byte string”.)

> It requires thinking at the wrong level, at the implementation level
> instead of the level of Python code. If we define "value" to mean the

> invisible, inaccessible reference, then that leaves no word to
> describe was the string "spam" is.

Fine, the value is the string. No problem there.

But the data model of Python doesn't fit well with the ideas that the
term “variable” connotes for most programmers: a box, perhaps of a rigid
shape (data type) or not, which is labelled ‘x’ and nothing else. For
another variable to have an equal value, that value needs to be copied
and put in a separate box; or perhaps some special reference to the
original needs to be made and placed in a box.

Saying “variable” and “has the value” just invites baggage needlessly,
and creates many assumptions about Python's data model which has to be
un-done, often after much false mental scaffolding has been built on
them by the newbie and needs to be dismantled carefully.

As we all know, Python doesn't work as the term “variable” implies for
many. Rather, ‘x’ isn't a container at all, but an identifier only. It's
more like a paper tag which can be tied to objects; that brings a bunch
of useful implications:

* that the paper tag is tied to only one object

* that a paper tag tied to no object is rather useless

* that many paper tags can be tied to the same object

* that the paper tag is only loosely associated with the object and can
be removed and tied to a different object, without any change to the
objects themselves

* that the object doesn't necessarily have any tag at a given point in
time

* that the tag with its string is useful to find the object even without
a name on the tag (the concept of other non-name bindings to objects,
e.g. list items)

All those implications of the “paper tag” analogy are helpful in
thinking about the Python data model. And those implications don't even
have to be explicitly stated in order to help.

So instead of inviting confusion with “variable ‘x’ has the value
"spam"” I prefer to say “name ‘x’ is bound to the value "spam"”.

> The intellectual contortions that some people will go through to
> hammer the square peg of actual programming language behaviour into
> the two round holes of "pass by value" and "pass by reference" never
> cease to astonish me.

I maintain that avoiding the use of the term “variable”, and gently
correcting those who use it in the context of Python (with humility in
the face of the fact that the Python documentation liberally uses the
term), can short-circuit a lot of that needless confusion.

Python isn't pass by anything. Nothing gets copied, nothing gets passed;
when a function is called with an object as a parameter, the object
stays put, and simply gets a new temporary name bound to it for the
function's use.

Speaking of objects (or values) with names bound to them helps that
explanation in a way that the traditional image of “variables” does not.

> > Whatever, a rose by any other name...)
>
> Do you really think that roses would be the symbol of romantic love if
> they were called "disgusting stink-weeds of perversion and death"?

Juliet's point stands, though: they would still smell as sweet, and the
term you describe would be unlikely to catch on since it doesn't
describe them well at all.

--
\ “I like to fill my bathtub up with water, then turn the shower |
`\ on and pretend I'm in a submarine that's been hit.” —Steven |
_o__) Wright |
Ben Finney

harrismh777

unread,
May 4, 2011, 5:49:25 PM5/4/11
to
Hans Georg Schaathun wrote:
> That does not in any way impugn C..;.
> : quite the contrary, given enough time, C is better suited for modeling
> : on a von Neumann processor, period.
>
> What has that got to do with abstraction?

Everything, really.

Folks seem to think that because they are doing abstraction at a
high-level (well, they never maybe programmed at a lower level) that
abstraction somehow 'requires' a high level language. (not true)

Back in the day, our abstractions were encapsulated not in source, but
in psuedo-code, flow-charts, diagrams, and sometimes pretty pictures. It
all ended up in assembly and machine code.

Today, high-level languages like Python (and others) allow programmers
to place some of their abstraction into their source code directly. This
does not make the high-level language any more 'suited' to abstraction
than any other lower-level language; because the abstraction is a mental
process not a language feature. It all ends up in assembly and machine
code.


kind regards,
m harris

John Nagle

unread,
May 4, 2011, 5:52:11 PM5/4/11
to
On 5/4/2011 3:51 AM, Steven D'Aprano wrote:
> On Wed, 04 May 2011 02:56:28 -0700, Devin Jeanpierre wrote:
>
>> Python is pass-by-value in a
>> meaningful sense, it's just that by saying that we say that the values
>> being passed are references/pointers. This is maybe one level of
>> abstraction below what's ideal,
>
> "Maybe"?
>
> Given the following statement of Python code:
>
>>>> x = "spam"
>
> what is the value of the variable x? Is it...?

>
> (1) The string "spam".
>
> (2) Some invisible, inaccessible, unknown data structure deep in the

> implementation of the Python virtual machine, which the coder cannot
> access in any way using pure Python code.
>
> (Possibly a pointer, but since it's an implementation detail, other
> implementations may make different choices.)
>
> (3) Something else.
>
>
> I argue that any answer except for (1) is (almost always) counter-
> productive: it adds more confusion than shedding light. It requires

> thinking at the wrong level, at the implementation level instead of the
> level of Python code. If we define "value" to mean the invisible,
> inaccessible reference, then that leaves no word to describe was the
> string "spam" is.
>
> (I say "almost always" counter-productive because abstractions leak, and
> sometimes you do need to think about implementation.)

Yes. In Python, the main leak involves the "is" operator and the
"id()" function. Consider:

>>> x = "spam"
>>> y = "spam"
>>> x == y
True
>>> x is y
True
>>> z = x + 'a'
>>> z = z[:4]
>>> z
'spam'
>>> x is z
False
>>> x == z
True
>>> id(x)
30980704
>>> id(y)
30980704
>>> id(z)
35681952

There, the abstraction has broken down. x, y, and z all reference
the value "spam", but they reference two, not one or three, instances
of it.

Arguably, Python should not allow "is" or "id()" on
immutable objects. The programmer shouldn't be able to tell when
the system decides to optimize an immutable.

"is" is more of a problem than "id()"; "id()" is an explicit peek
into an implementation detail. The "is" operator is a normal
part of the language, and can result in weird semantics. Consider

>>> 1 is (1+1-1)
True
>>> 100000 is (100000+1-1)
False

That's a quirk of CPython's boxed number implementation. All
integers are boxed, but there's a set of canned objects for
small integers. CPython's range for this is -5 to +256,
incidentally. That's visible through the "is" operator.
Arguably, it should not be.

John Nagle

Grant Edwards

unread,
May 4, 2011, 5:57:29 PM5/4/11
to
On 2011-05-04, harrismh777 <harri...@charter.net> wrote:
> Grant Edwards wrote:
>>> We do not consider passing a pointer as*by value* because its an
>>> > address; by definition, that is pass-by-reference.
>> No, it isn't. It's pass by value. The fact that you are passing a
>> value that is a pointer to another value is not relevent.
>>
>
> @ Edwards, &Schaathun
>
> You are most definitely mistaken.

The "pass by value" and "pass by reference" parameter passing
mechanisms are pretty well defined, and C uses "pass by value".

> I understand that semantically some people insist that when C
> receives parms as pointers that pass-by-reference is only being
> simulated.

And they are right.

> If I want to pass values to my C functions, I can. If I want to pass
> references to my C functions, I can.

We're not talking about what _you_ do. We're talking about what the C
_compiler_ does. The C compiler passes by value -- always.

> If I want to implement a C language that does not use pointers directly
> (hides them) I can implement pass by reference completely (on the
> surface).

That wouldn't be C.

> In fact, I can implement the C compiler so that pass by value is not
> allowed! [ it wouldn't look much like C, but its do-able ]

If you don't pass by value, it's not a C compiler.

> Everyone forgets that their high-level language is not 'really'
> what's working... gcc does not produce machine code... it produces
> assembler instructions that are passed to a translator... you can
> interrupt the process and have it produce the assembly instructions
> so you can see them if you want to... the point being, after all is
> said and done, all you can do with today's von Neumann processors is
> pass data directly (value) or indirectly (reference).

I have no idea what your point is.

At the machine level, there _is_ nothing but values. You can use a
value as an integer, or as a pointer. It's still just a value. But
we're talking about parameter passing mechanisms defined by high-level
language specifications -- particularly C.

--
Grant Edwards grant.b.edwards Yow! It was a JOKE!!
at Get it?? I was receiving
gmail.com messages from DAVID
LETTERMAN!! !

Ian Kelly

unread,
May 4, 2011, 6:22:42 PM5/4/11
to Python
On Wed, May 4, 2011 at 3:35 PM, harrismh777 <harri...@charter.net> wrote:
> Grant Edwards wrote:
>>>
>>> We do not consider passing a pointer as*by value*  because its an
>>> >  address; by definition, that is pass-by-reference.
>>
>> No, it isn't.  It's pass by value.  The fact that you are passing a
>> value that is a pointer to another value is not relevent.
>>
>
> @ Edwards, &Schaathun
>
> You are most definitely mistaken.   See:
>
> http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr233.htm

That source actually supports the claim that pass-by-pointer falls
under pass-by-value. It reads, in part (emphasis added):

> In C++, the reference parameters are initialized with the actual arguments when the function is called. In C, the pointer parameters > are initialized with pointer _values_ when the function is called.

However, I hope we can all agree that pass-by-pointer shares certain
features with both pass-by-value and pass-by-reference, and there are
perfectly reasonable arguments for lumping it in either category, yes?

harrismh777

unread,
May 4, 2011, 8:46:57 PM5/4/11
to
John Nagle wrote:
> Arguably, Python should not allow "is" or "id()" on
> immutable objects. The programmer shouldn't be able to tell when
> the system decides to optimize an immutable.
>
> "is" is more of a problem than "id()"; "id()" is an explicit peek
> into an implementation detail.

Yes, yes, yes... and I'll go you one more...

... Python should optimize on *all* immutables when possible.


For instance:

a = (1,2,3)
b = (1,2,3)

a == b True

a is b False

To be consistent, in this case and others, a and b should reference
the same immutable tuple.


Or, as stated earlier, Python should not allow 'is' on immutable objects.


kind regards,
m harris

harrismh777

unread,
May 4, 2011, 8:51:15 PM5/4/11
to
Ian Kelly wrote:
> However, I hope we can all agree that pass-by-pointer shares certain
> features with both pass-by-value and pass-by-reference, and there are
> perfectly reasonable arguments for lumping it in either category, yes?

Yes.

harrismh777

unread,
May 4, 2011, 9:11:02 PM5/4/11
to
Grant Edwards wrote:
> The "pass by value" and "pass by reference" parameter passing
> mechanisms are pretty well defined, and C uses "pass by value".

Yeah, that's kind-a funny, cause I'm one of the guys (old farts) that
helped define them....


The problem you're having here is that you're thinking of parameter
passing 'mechanisms' and not focusing on the definition of the terms.

A reference is a pointer (an address).

A value is memory (not an address).


These definitions go all the way back before the 8080, or the 6502, 8
bit processors. Pass by reference has 'always' meant pass by using a
memory address (indirect addressing); a reference has always been a
memory pointer.


If I call a function in C, and pass-by-value, the data's 'value' is
placed on the stack in a stack-frame, as a 'value' parm... its a copy of
the actual data in memory.

If I call a function in C, and pass-by-reference, the data's 'address'
is placed on the stack in a stack-frame, as a 'reference' parm... no
data is copied and the function must de-reference the pointer to get to
the data.... this is by definition.

There may be some language somewhere that does pass-by-reference which
is not implemented under the hood as pointers, but I can't think of
any... 'cause like I've been saying, way down under the hood, we only
have direct and indirect memory addressing in today's processors. EOS.

If you pass a parm, you can either pass a copy (value) or pass a
reference to its location (not a copy, a reference).


kind regards,
m harris


Mark Hammond

unread,
May 4, 2011, 10:09:08 PM5/4/11
to harrismh777, pytho...@python.org
On 5/05/2011 11:11 AM, harrismh777 wrote:

>> The "pass by value" and "pass by reference" parameter passing
>> mechanisms are pretty well defined, and C uses "pass by value".
>
> Yeah, that's kind-a funny, cause I'm one of the guys (old farts) that helped define them....

Cool - please tell us more about your involvement in that. Obviously
lots of people were in the industry then, but only a select few would be
able to claim they helped define those terms.

> There may be some language somewhere that does pass-by-reference which
> is not implemented under the hood as pointers, but I can't think of
> any... 'cause like I've been saying, way down under the hood, we only
> have direct and indirect memory addressing in today's processors. EOS.

What about Python, where passing an integer to a function passes a
pointer to an int object, but that function is able to change the value
of the variable locally without changing the passed object (indeed, it
is impossible to change the passed integer)?

So given the definitions above, Python uses a by-reference mechanism but
(in some cases) has by-value semantics.

While I understand exactly how things work (so don't need an
explanation), the point is that for anything close to a high-level
language, things aren't as black and white as they are for the low-level
languages...

Mark

Chris Angelico

unread,
May 4, 2011, 10:43:04 PM5/4/11
to pytho...@python.org
On Thu, May 5, 2011 at 7:43 AM, Ben Finney <ben+p...@benfinney.id.au> wrote:
> * that the paper tag is tied to only one object
>
> * that a paper tag tied to no object is rather useless
>
> * that many paper tags can be tied to the same object

I disagree minorly; a tag tied to no object is quite useful in some
circumstances. You can ditch the concept by having a special object
that's called "No Object" (Python does this, with None), or you can
allow your tag to point nowhere (C does this, with null pointers). The
difference is semantic; either way, your tag can point to any object
or it can point nowhere. (Pike goes for a slightly different approach;
any variable, regardless of its stated types, may legally hold the
integer 0. It acts somewhat as a null pointer, but it isn't really.)

Chris Angelico

Tim Roberts

unread,
May 4, 2011, 11:23:36 PM5/4/11
to
harrismh777 <harri...@charter.net> wrote:
>
>If I call a function in C, and pass-by-value, the data's 'value' is
>placed on the stack in a stack-frame, as a 'value' parm... its a copy of
>the actual data in memory.
>
>If I call a function in C, and pass-by-reference, the data's 'address'
>is placed on the stack in a stack-frame, as a 'reference' parm... no
>data is copied and the function must de-reference the pointer to get to
>the data.... this is by definition.

This is not correct. Consider an example.

int BumpMe( int * a )
{
return *a+3;
}

int Other()
{
int x = 9;
return BumpMe( &x );
}

That is not an instance of passing an "int" by reference. That is an
instance of passing an "int *" by value. The fact that the parameter "a"
in BumpMe happens to be an address is completely irrelevent to the
definition of the parameter passing mechanism.

C has pass-by-value, exclusively. End of story.

>There may be some language somewhere that does pass-by-reference which
>is not implemented under the hood as pointers, but I can't think of
>any...

Fortran had genuine pass-by-reference. In Fortran, you could write a
program like this:

SUBROUTINE CONFUSION(IVALUE)
INTEGER IVALUE
IVALUE = IVALUE + 1
END

PROGRAM MAIN
CONFUSION(4)
END

That program would actually modify the value of the constant 4. Such an
abomination is simply not possible in C. Is that implemented
under-the-hood with pointers/addresses? Of course it is. However, that
does not change the parameter passing model as defined by the language
specification.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Gregory Ewing

unread,
May 4, 2011, 11:48:51 PM5/4/11
to
Hans Georg Schaathun wrote:
> Is transmission by name the same as call by object?

No, it's not. With call-by-name, the caller passes a
small function (known as a "thunk") that calculates the
address of the parameter. Every time the callee needs to
refer to the parameter, it evaluates this function.

This allows some neat tricks, but it's massive overkill
for most uses. In later languages, the functionality of
call-by-name has been replaced by the ability to explicitly
pass functions as parameters.

> Anyway, I have never seen anyone counting more than
> three ways of doing this ...

There are other possibilities, such as value-result,
where a local copy is made and its final value is
copied back before returning. I think Fortran is
defined in such a way that this is an acceptable way
of implementing parameter passing. It's also the
only way of getting anything akin to by-reference
over an RPC connection.

But for most situations, by-value and by-reference
cover anything you might want to do. And if you
have a dynamic data model like Python, you don't
even need by-reference.

--
Greg

harrismh777

unread,
May 5, 2011, 12:01:13 AM5/5/11
to
Mark Hammond wrote:
> What about Python, where passing an integer to a function passes a
> pointer to an int object, but that function is able to change the value
> of the variable locally without changing the passed object (indeed, it
> is impossible to change the passed integer)?
>
> So given the definitions above, Python uses a by-reference mechanism but
> (in some cases) has by-value semantics.

Yeah, Mark, the trouble is that the concepts (by-value, or
by-reference) have morphed into a concept(s) that say something of what
should or should not happen within scopes (or, in the case of Python,
namespaces) and says something less about what 'reference' or 'value'
mean as terms for data. So, again, its semantics... not black and white,
as you say and some of both|and.

If C were 'strictly' pass-by-value (that is what the K&R states,
sec. 1.8, p27 2nd ed) and had no concept of indirect memory addressing
(memory references is what we called them in the early days ca. 1970~)
in the form of pointers, then all of this semantic discussion would be
mute. But, 'C' does provide for pointers which are used by all 'C'
programmers to firmly provide pass-by-reference in their coding (C++
also, by the way). My 'C' functions can most definitely modify the parms
passed in from their calling functions by simply 'de-referencing' the
parms. This is done all the time--- and a good thing too, since nobody
would want to pass a list by value, or worse yet a linked list with a
couple of thousand nodes, by value.

So, I argue that its silly to say that because the parameter passing
'mechanism' of the 'C' language is pass-by-value (see K&R) that 'C' is a
pass-by-value language, when clearly 'C' programmers use
pass-by-reference routinely in their 'C' coding. This is quite different
than some flavors of Fortran or Pascal where the called routines had
access to the original vars--- which had more to do with scope than it
did with parameter passing or indirection. In 'C' if I want to I can
live with pass-by-value... or, I can live with pass-by-reference
nicely... and its up to me... not language constraints. Again, it seems
that some folks want to pigeon hole this concept into one or the other
(and it clearly can be) but usually it is a combination of the two (both
| and).

kind regards,
m harris

John Nagle

unread,
May 5, 2011, 12:32:59 AM5/5/11