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

Derek Martin code at pizzashack.org
Sun Nov 23 16:24:05 CET 2008


On Tue, Nov 18, 2008 at 09:23:30AM +0000, Steven D'Aprano wrote:
> > 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.
> 
> Well, sure, if you care *that much* about potentially trivial aspects. I 
> have a ten dollar note with a spec of dirt on one corner, and a ten 
> dollar note with a slightly larger spec of dirt on a different corner. 
> I'd agree with you that they are not "the same" in every aspect, but 
> they're the same in every way I care about.

It's trivial to show that this is not necessarily the case -- you just
haven't thought of all the ways in which a difference might matter to
you..

Suppose that one of the 10-dollar bills had a serial number which was
never printed by the government (i.e. it is counterfiet).  Are they
still the same in every way that you care about?

What is the value of these two objects?  Is it the same?

The answer, in both cases, is, "it depends."  The value of both is
context-specific, just as I argue is the value of a python object.
First let's briefly examine the value of the counterfiet:

The "intrinsic" value (or rather, the value generally accepted by the
authorities) of the counterfeit is zero.  However, if you have one in
your hand, and you pass it to a merchant who is not able to detect
that it is a counterfeit, then, isn't its value $10 in that context?
If you walk away from the merchant with $10 worth of goods (and/or
change in non-counterfeit currency), then I would say it would have to
be, *in that context*.  

Now suppose that the merchant is actually a U.S. Secret Service agent
investigating counterfeit money.  He notices the bill and arrests you.
What is the value of the bill now?  I doubt you could really measure
it, except perhaps in terms of the amount of money it would cost you
to defend yourself in court (if your case went to court), the amount
of hastle to deal with the authorities, etc.  Suffice it to say that
the value is rather negative, possibly with a very high magnitude,
depending on what happens next.

What about the genuine $10 bill?  

If you take it to your local mall, or your local gas station, or your
corner grocer, it's clearly worth $10... or is it?  Prices of gasoline
vary from station to station, city to city, state to state, even if
the gas is sold by the same company.  A can of peas might be $0.89 at
a market in New Hampshire, or the same can of peas might be $1.59 at a
market in down town Manhattan.  And if you take your $10 bill to pay
for your favorite cup of coffee at Starbucks in your city, it might
cost you $4 with change back of $6...  But if you bring that same $10
bill to a Starbucks in a small city in Germany, good luck getting any
coffee...

Just as in the real world, the value of a Python object depends on the
context in which it is evaluated.

> > 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.
> 
> Philosophically, no, not irrelevant. You haven't explicitly defined "the 
> same" in enough detail to make that call. Perhaps because the objects are 
> in different locations (different IDs) is enough to make them different, 
> even if everything else about them is identical.
> 
> For example, consider the two electrons around a helium nucleus. They 
> have the same mass, the same speed, the same spin, the same electric 
> charge, the same magnetic moment, they even have the same location in 
> space (technically, the same wave function). They are identical in every 
> possible way. Are they the same electron, or two different electrons? 
> What does the question even mean?
> 
> My point is that as a philosophical position, identity may or may not 
> count as "sameness". It depends on the circumstances.
> 
> 
> 
> > 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.
> 
> Philosophically, sure, but practically, perhaps not. The foo attribute 
> may be entirely irrelevant to your purposes, the equivalent of a random 
> speck of dirt or a slight tear on a ten dollar note.
> 
> Luckily, Python doesn't try to guess whether differences are significant 
> or not. You can override the __eq__ method on classes and choose for 
> yourself what properties of a class are differences that make a 
> difference and which are mere markers of no particular concern.
> 
>  
> > 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!? 
> 
> That's because you haven't asked the objects themselves if they are the 
> same. Not every aspect of objects are implemented as attributes.
> 
> 
> 
> > 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?
> 
> Of course you do. Just look at the object and you will see it is a 2.
> 
> 
> 
> > Why isn't
> > there a .value attribute or something holding 2?
> 
> Why should there be a value attribute? Python attributes are just a 
> particular interface for accessing data. It's not the only possible 
> interface.
> 
> 
> > We look at everything we can 
> 
> You forgot to look at the object as a whole. Consider a pair of trousers. 
> You're rifling through the pockets of one looking for a coin or a wallet 
> or some other object to distinguish it from another pair of trousers, 
> without noticing that one is made of blue cotton and the other is green 
> spandex.
> 
> 
> 
> > but we can see no difference between the two objects, nothing
> > that tells us that one is a 2, and the other a 3.
> 
> The objects themselves tell us that they are 2 or 3. They don't need an 
> extra attribute, and in fact the implementation of int objects don't 
> allow for extra attributes because they have no __dict__ to store them in.
> 
> 
> > 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".
> 
> I don't think this is a valuable distinction to make. What's the 
> intrinsic value of a dict?
> 
> 
>  
> > 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.
> 
> Let's not.
> 
> The type of an object is a label that tells Python where to look in order 
> to interpret the object. It is certainly *not* the attributes on the 
> object:
> 
> >>> type(5)
> <type 'int'>
> 
> 
> 
> > "value" is then what is left: the object's local attributes and
> > the intrinsic-value described above.
> 
> What do you mean by "local attributes"?
> 
> Do you mean instance attributes? That's well defined: an attribute is an 
> instance attribute if it is in obj.__dict__. It is a class attribute if 
> it is in obj.__class__.__dict__.
> 
> (Slots make this a little more complicated in practice, but we can ignore 
> them for now.)
> 
> 
> > 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 think we gain anything from distinguishing value and intrinsic 
> value, except confusion.
> 
> 
> How do you deal with compound objects. What's the value of [1, 2, 3] if 
> it isn't "the list consisting of ints 1, 2 and 3"?
> 
> And recursive objects?
> 
> class Parrot:
>     def __init__(self):
>         self.me = self
> 
> p = Parrot()
> 
> a = []
> a.append(a)
> 
> 
> 
> 
> > 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.
> 
> Think about lists. The "intrinsic" value of a list is the items in the 
> list itself, if it is anything, but you have an interface for looking at 
> them individually:
> 
> alist[i]
> 
> Here's another problem with your idea of "intrinsic value". Consider a 
> list. The list object in CPython is an array of cells, containing data. 
> Some of those cells are in use, some of them are free, but regardless of 
> whether they are free or in use they still have data in them. (The data 
> may be obsolete in the case of the free cells. The list object also 
> includes a cell which records the number of cells in the array, and 
> another cell recording private information of use to the Python garbage 
> collector. These cells are not necessarily the same size.
> 
> Are they part of the "intrinsic value"? You can't access them via 
> attributes.
> 
> What if we use another implementation of list, say, a linked list? What 
> if we use PyPy, an implementation of Python in Python, and (for the sake 
> of the argument) lists are implemented as follows:
> 
> class list(object):  # untested
>     def __init__(self, values):
>         for i, x in enumerate(values):
>             setattr(self, i, x)
> 
> (This would make a lousy implementation. Don't try it!) Does that mean 
> that the value of [1, 2, 3] depends on the implementation of Python you 
> create it under?
> 
> 
>  
> > For example, you can define the value of None however you want, but it
> > seems clear that it has (and needs) no intrinsic-value.
> 
> To me, that seems just as silly as arguing that zero is not a number, or 
> that white pixels are "nothing" and black pixels are "something".  Or 
> maybe they should be the other way around?
> 
> None is None. It is what it is, and that is it's value. What *meaning* 
> you put to that is up to your program. It is a convention, a useful 
> convention but still merely a convention, that None is used to represent 
> values which otherwise would be missing, if there could be actual holes 
> in Python code.
> 
> 
> > Same with
> > object(). I now understand why the only way to describe the object
> > int(2) is requires using str/repr 
> 
> Not true.
> 
> >>> x == int(3)
> >>> if x == 2:
> ...     print "x has the value two"
> ... elif x == 3:
> ...     print "x has the value three"
> ...
> x has the value three
> 
> 
> At no stage did I call str() or repr() on x.
> 
> 
> > 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".
> 
> Expressions always evaluate to objects (unless they don't return at all). 
> The value of an expression is the object it evaluates to. What is wrong 
> with that claim? Why do you believe that we need a more complicated, 
> convoluted understanding of value? What problem are you trying to solve?
> 
> 
> 
> -- 
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list

-- 
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20081123/b268bb2d/attachment.pgp>


More information about the Python-list mailing list