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

rurpy at yahoo.com rurpy at yahoo.com
Sat Nov 15 22:42:33 EST 2008


[Tried multiple times to post this but Google errors
out so will try posting in two parts... this is part 2]
On Nov 14, 11:51 pm, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Fri, 14 Nov 2008 22:56:52 -0500, Terry Reedy wrote:
>> rurpy at yahoo.com wrote:
>>> On Nov 13, 4:53 pm, Terry Reedy wrote:
>>>> rurpy at yahoo.com wrote:

>>> * Can I create an object that has a value that
>>>  is the same as int(3) without somehow using an int(3) object in its
>>>  construction?
>>
>> Yes: 1 + 2
>> Yes: mpz(3) where mpz is multi-precision int class with same set of
>> possible values as Python ints.
>>
>> ??? 3.0
>> ??? Fraction(3,1)
>>
>> While Python sees these as *equal*, one could say they are not the same
>> because they indicate members of different (non-isomorphic) universes.
>
> Whether we wish to say that mpz(3) has the same value as int(3) depends
> on what we care about, and we only care about that because our data types
> are leaky abstractions. In principle, we should be indifferent to whether
> x is int(3), float(3.0), mpz(3), or any other instantiation of the
> abstract numeral three. In practice, we're not indifferent: we prefer
> ints for mpz objects for some purposes, but not for others. If we care
> about the specifics, then we might say they have different values
> (because they have different types, and therefore different
> characteristics). If we care only about the thing they represent, the
> abstract number three, then we'd say that they have the same value.

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.

>>> * Do all objects have values? (Ignore the Python
>>>  docs if necessary.)
>>
>> If one allows null values, I am current thinking yes. Still, numbers,
>> characters, and collections thereof of what code is usually about.
>
> I would say that all objects *are* values, rather than *have* values. The
> value of None is the object None, which is a concrete instantiation of a
> selected subset of behaviour of the null object pattern.
>
>>> * What is the value of object()?
>>
>> Essentially none, other than bool(object()) == True. Ditto for None,
>> other than bool(None) == False. Otherwise, None and object convey no
>> information.
>
> 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?  In the
My_int example above, is the .foo attribute of interest
or not?  How would I decide?  How would you decide?
I was also going to ask about changing methods, but I
see you consider that below.

> In practice, I'd say that object() is one of those cases where we should
> include identity in the value. Although we're indifferent as to *which*
> object() instance we get, once we've got one, we care whether other
> instances are the same instance or different ones. Imagine that object()
> keeps a cache of instances, and returns one instead of creating a brand
> new object. We don't care which instance we get, or even whether it comes
> from the cache or is created fresh. But once we have one, we care about
> the identities of others:
>
> special = object()  # we don't care which object instance we get
> if special is some_other_instance():
>     print "Match!"
>
>>> * Does an object's behavior (methods) affect
>>>  its value?
>>
>> My first answer is No.  Instance methods are attributes of a class and,
>> in most cases, the value of a class.  In those cases in which the class
>> of an object can be and is changed to another class, the interpretation
>> of the value/info of the instance could change and one might claim that
>> the effective value and hence the value of the object has changed and
>> hence the answer could be Yes.  But this is extremely rarely done and I
>> could claim that this is a shortcut for creating a new object and
>> deleting the old.
>
> 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.

> 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.  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.  (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.

> 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?

> 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.  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.

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.

> [snip]
>>> Or perhaps value is some sort of useful but fundamentally undefinable
>>> concept
>>
>> Either yes or defined in terms of information or universes.
>>
>>> that disappears when looked at too closely
>>
>> No.
>
> I would say that although value is dependent on context, that's no excuse
> for concluding that it has no meaning. If you look too closely at
> *anything*, it becomes fuzzy. (Well, with the possible exception of pure
> mathematics.)

But it is desirable to define with as little
fuzz as possible :-)




More information about the Python-list mailing list