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

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Nov 16 04:50:06 EST 2008


On Sat, 15 Nov 2008 19:42:33 -0800, rurpy wrote:

> You are saying there is no objective definition of "value".  I disagree.
>  I think one can define value in a useful way that is precise,
> objective, and useful.

No, I'm not saying that there is no objective definition of value. I'm 
saying that the objective definition depends on the circumstances. I 
believe that it is foolish to try to avoid context-sensitivity in your 
definition of value.

It is possible though. You can consider everything which makes a thing 
different from another thing, but taken all the way that leads to 
deciding that this sentence:

"The cat sat on the mat."

does not have the same value as this sentence: 

"The cat sat on the mat."

because the second one comes further down this document. (I trust that 
you understand that sentences are compound symbols, expressions if you 
prefer.) I would argue that this is usually a silly distinction, since 
the position of a sentence in a document rarely makes a difference to the 
meaning (the value) of that sentence. But not always silly. Imagine the 
following:

"Harry pointed his massive gun at the fugitive.

'Do you feel lucky?'

[... much later on...]

Working undercover at the casino, Harry adjusted his uniform, brushed a 
speck of imaginary dust off the sleeve, and greeted the billionaire. 
'Good evening Sir, welcome to the Starlight Casino, your first drink is 
on the house. Could I interest you in a game of friendly poker? Do you 
feel lucky?'"

Is there any doubt that the same symbol can denote a different meaning (a 
value) under different circumstances?



>> I would say that the "everything of interest" I referred to above is
>> the empty set: object() has little or no state. But of course having no
>> state is itself a state, in the same way that 0 is a perfectly good
>> integer.
> 
> "interest" is pretty subjective, isn't it?

Of course not. If we agree that we want something that undergoes integer 
addition as defined by mathematicians, there's nothing subjective about 
that. That will immediately rule out vast numbers of values: None, dicts, 
lists, strings, and so forth. But it still allows floats, ints, mpz 
objects, etc., and in principle we're indifferent to which of them we 
get. We may choose to arbitrarily convert objects from one type to 
another, whatever is convenient, so long as they can be added together. 
Any other property of these types is a red stripe, to be kept if 
convenient, discarded if needed, but always ignored.



> In the My_int example above,
> is the .foo attribute of interest or not?  How would I decide?

That depends on what you wish to do with the object. If you just want to 
add it to an int, then it is of no interest. It's a red stripe. But if 
you want to pass it on to another function which may treat the foo 
attribute as significant, then you can't afford to just throw it away. In 
other words, you care about the attribute, even if you aren't using it 
yourself.



>> I would say that the answer to this is, "Would you like to include
>> behaviour in value?". Let me give you an example:
>>
>> class String(string):
>>     def upper(self):
>>         return "spam"
>>
>> s1 = "Norwegian Blue"
>> s2 = String("Norwegian Blue")
>>
>> Do s1 and s2 have the same value?
> 
> Using my definition of value, the answer is an unambiguous yes.

But that implies that you should be able to use s2 anywhere that you can 
use s1, and that's clearly not true:

assert len(s2.upper()) == len(s2)

Since you can't use s1 and s2 in the same places, how can you justify 
saying the have the same value?

I have an answer to that: if I don't care about upper(), then I'm happy 
to consider them to have the same value. If I do care about the invariant 
above, then I can't.


 
>> Using definition (1) above, we can see that the names s1 and s2 refer
>> to different objects, so the names have different values.
> 
> No, they refer to different objects.  

"No"? That's what I said.


> The object str("Norwegian Blue")
> has a value, tucked away inside it somewhere, of some implementation
> defined bits that encode "Norwegian Blue".
> String("Norwegian Blue") is a subclass of str and has the same value. 

Sure, in the specific example I gave, but in general this is not 
necessarily the case. Consider this fact: every string can be represented 
by a sequence of bytes. A byte can be considered a digit in base 256. 
"Norwegian Blue" considered as a number in this fashion is 
1590857700756072424900433200051557. With sufficient effort, I could 
inherit from long, instead of str, and duplicate the exact behaviour as 
str. Subclassing is a red-herring.



> (Actually, we don't really care about bit patterns, it is enough to
> declare that the values stored in the objects are the same because
> that's how the language is defined.) If they appear different when
> .upper() is called, it is because the two types (i.e. behaviors) are
> different.

But behaviour defines what we interpret the object as. The same bit 
pattern represents the number 1590857700756072424900433200051557 and the 
string "Norwegian Blue". Without behaviour, how could you tell them apart?


 
>> Using definition (2), the objects s1 and s2 have different concrete
>> expressions, and so they are different values. (Remember: the object is
>> the value.)
> 
> Sorry, I disagree.
> 
>> But from definition (3) they both represent that same abstract string,
>> so if I care only about that level of description, I'd say yes they
>> *have* the same value but *are* different values.
> 
> They "have" the same value, it is the difference in their behavior
> (type) that produces different results from .upper().
> 
> class xint (int):
>     def bigger(self):
> 	"return a number bigger than me."
> 	return self + 2
> class yint (xint):
>     def bigger(self):
>         "return a number very much bigger than me."
> 	return self + 1000
> a = xint(5)
> b = yint(5)
> 
> Do you claim that a and b really have different values?

That depends on why I'm asking. If all I want is a number that I can add 
to 3 and get 8, then I'm indifferent to the choice between a and b and I 
would say that their values are not different in any way I care about. If 
I want a number than I can add to 3, *and* that returns a number larger 
than 1000 when I call the bigger() method, then a will not do but b will 
be fine. In this case, I would argue that their values are different.


 
>> Assuming I cared about the behaviour of upper(), then s2 is probably
>> not suitable for my purposes and so I would like to distinguish s1 from
>> s2. I'd insist that they have different values which merely looked the
>> same under equality. To use the bank note analogy, then s1 is legal
>> tender but s2 is just a very good forgery.
>>
>> But note that to a collector of forgeries, s2 might be more valuable
>> than s1, and presumably the writer of class String had a reason for the
>> behaviour given. The answer to the question "do s1 and s2 have
>> different values" will depend on why you are asking.
> 
> That is ok if one is happy with such a squishy, subjective definition of
> value.

There's nothing subjective about it. Two people, given the same 
constraints, should be able to agree on whether two objects have the same 
value in the context of the problem they are trying to solve.


> But I propose that one can define value in a precise way that
> captures what most people think of as value, and avoids confusing
> objects (or references to them) and the value of objects.

Good luck. I think you're chasing your own shadow.


> Given that "value" is one of the three defining characteristics of
> objects, a (the?) central concept of Python, I don't see how such a
> subjective definition as yours is workable.

You've said that attributes are not part of the value, and thus denied 
that the state of an object is the object's value. Given that, I don't 
think your definition is workable. I think it's counter-productive to try 
to define value in such a way that most Python objects have no value, 
especially the most high-level objects.



-- 
Steven



More information about the Python-list mailing list