Official definition of call-by-value (Re: Finding the instance reference...)

rurpy at yahoo.com rurpy at yahoo.com
Sun Nov 16 18:46:54 EST 2008


Since many responses to my definition of
value raised similar points, I will try
and respond generally here.

In hindsight, I should not have used the
word "value"; it is far too overloaded with
preexisting semantics for me to have attempted
to redefine it, even if it is the word used
(but not defined) in the Python Reference
Manual.

Let me try again, in a slightly different
way and using slightly different terminology
in the hope we can avoid the fascinating
but basically irrelevant philosophical
digressions into form and ideal, the nature
of nothingness, etc. :-)

Suppose I have two objects and want to
know if they are the same or not.  They
are distinct objects so I know that their
id()'s are different but that's not what
I'm interested in.  Example

  class A(object): pass
    def __init__ (self): self.foo = 1
  class B(object): pass
    def __init__ (self): self.foo = 2
  a = A()
  b = B()

How I can answer the question, "are the
objects a and b the same or different"?
I can look at every aspect of each object,
looking for something that is different.
What are the aspects of the object that I
can look at?

id(obj) will give me the identity but I know
that will be different and so its irrelevant.
What else can we look at?  We can go through
each attribute of the objects looking for an
attribute that one has and the other doesn't,
or for attributes of the same name that are
different.

We look at .__class__, .__delattr__, .... and
so on and they are all the same until we come
to .foo and note that a.foo and b.foo are different.
One is an int(1) object, the other is an int(2)
object.  So we can say that a and b are different.

Lets do the same with these two objects:

  a = int(2)
  b = int(3)

When we do that, we find no difference!  Every
attribute is the same in both a and b!  WTF!?
But we know when we call a's .__add__ method [*1]
with the argument 1, we get a different result
than when we call b's __add__ method with the
argument 1.

Somehow, built into the internal representation
of the int(2) object, is some representation of
the number 2 and the int(2) object's __add__() method
accesses this representation in order to decide that
it has to create an int(3) object to return, rather
than creating an int(47) object to return.

But why don't we see this "2" when we examine the
object?  Why isn't there a .value attribute or
something holding 2?  We look at everything we
can but we can see no difference between the two
objects, nothing that tells us that one is a 2,
and the other a 3.

So clearly the 2-ness of int(2) is built into
the object and is not visible *except* in it
behavior.  The int(2)'s __add__ method knows
how to access it, so do __repr() and __str__()
and other methods.  But short of using those
methods, there is no way for me (the programmer
using Python) to access it.  The 2-ness is some
sort of intrinsic property of the int(2) object.
I will call it "intrinsic value".

The Python Reference Manual states that an object
consists of identity, type, and value.  "Identity"
seems to be non-controversial.

Let's take "type" as meaning the attributes an
object inherits from it's class.  "value" is then
what is left: the object's local attributes and
the intrinsic-value described above.

This seems to be the most common view of "value",
and similar to the one Fredrik Lundh takes in
  http://effbot.org/zone/python-objects.htm
which was pointed to in an earlier response
(he calls it "content")

One could also take all attributes accessible
through obj (its class' attributes as well as
its local attributes) as "type" leaving only
intrinsic-value as "value".
This was the view I proposed.

Or one could adopt what Terry Reedy called a
4-aspect view: an object is identity, class,
value (or local-state or something) and
intrinsic-value.

I don't understand Python well enough to defend
any of these descriptions (I now realize, despite
my previous postings to the contrary. :-)

But what I do defend is the concept of intrinsic
value which I have not ever seen explicitly stated
anywhere and which clarifies a lot of things for me.

For example, you can define the value of None
however you want, but it seems clear that it has
(and needs) no intrinsic-value.  Same with object().
I now understand why the only way to describe the
object int(2) is requires using str/repr whereas
with objects without an intrinsic value, I can
describe without needing str/repr.
I can think of expressions as always returning
objects, never "values".
Etc...

So, is this point of view any more acceptable?

[*1] I took note  of Terry Reedy's point that
a.__add__(b) is really int.__add__ (a, b) but
since the two descriptions are isomorphic at
the level I am discussing, it seemed clearer
to leave class out of it.



More information about the Python-list mailing list