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

rurpy at yahoo.com rurpy at yahoo.com
Sat Nov 15 14:17:07 EST 2008


On Nov 14, 8:56 pm, Terry Reedy <tjre... at udel.edu> wrote:
> rurpy at yahoo.com wrote:
>> On Nov 13, 4:53 pm, Terry Reedy wrote:
>>> rurpy at yahoo.com wrote:
>>>
>>>> I have yet to see any reasonable definition of a Python
>>>> value in the Python docs or elsewhere, despite the fact
>>>> that a value is one of the three defining characteristics
>>>> of an object, a central concept in Python.
>>> I noticed too.  My try:
>>>
>>> The value of an object is the information that the object represents (or
>>> that is stored with the object) that the interpreter uses to compute the
>>> value of a new object when you use the object in an expression.  For
>>> number objects, the number value.  For collection objects, the objects
>>> collected. For functions, the signature and function performed when called.
>>>
>>> How is that?
>>
>> I am starting with the idea that "value" is what we call
>> whatever it is that is the difference between, for example,
>> the objects int(3) and int(4).  While your definition
>> seems to be saying something similar it does not seem
>> very precise.

First of all, thanks.  Thanks to your answers I have
finally been able to formulate a concept of Python
values.  Now we'll see if it is valid/usable... :-)

> I think necessarily so, or rather, it can only be specific for each
> class.  In the formulation: an object has identify, class, and value,
> class and value are separated.  Others have said that type/class is a
> universe of possible values and operations on those values.  Each
> instance has a particular value. 'Universe of possible values' is vague
> until one gets specific.  For some classes, the possible values are
> rather complex.
>
>> How would I use your definition to answer the following
>> questions?
>>
>> * How does an object get a value?
>
> A Python interpreter, human or electronic, creates objects with values
> as directed by Python code.  How it does so is its private secret ;-).
> The directive code includes literals, expressions, and some statements.

OK.

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

OK, but my question was too strict.
"1 + 2" is shorthand for: int(1).__add__(int(2))
Rephrasing: is possible to create an object that has
a value that is the same as int(3) without somehow
using a method of the int class (or sub/super-class)
in its construction?
I think it is not possible in the Python language.
That is one could in theory have a float method,
to_int(), but it could not be implemented in the
Python language (as opposed to implemented in the
Python implementation) without using int(), or some
other callable that uses int().

> Yes: mpz(3) where mpz is multi-precision int class with same set of
> possible values as Python ints.

The argument to mpz() is int(3).

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

At this point, I would so say.

>> * Do all objects have values? (Ignore the Python
>>  docs if necessary.)
>
> If one allows null values, I am current thinking yes.

I don't see a difference between a "null value"
and not having a value.

> Still, numbers, characters, and collections thereof of what code is
> usually about.

Yes, which is why we have int, str, and list classes
which, unlike some others, can have values.

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

A method/function can use whatever characteristic of
its arguments that it wants.  For example, id() pays no
attention to the value of its argument, only its identity.
So we can say that the bool class constructor returns
True for all object except None.  Since None is a
singleton, bool() can identify it by identity, without
consideration of it's (non-existent I propose) value.

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

The value of a class is it's attributes?
Are you saying that attributes of an object are
part of its value?  That would mean that 'a'
and b' below have different values?

class My_int(int):
    def __init__(self): self.foo = None
a = int(3)
b = My_int(3)

I propose that attributes are not part of a class'
(or any other object's) value and that a class object
has no value.

> 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.
>
>> * If two objects have different unrelated types
>>  (i.e. not subclassed), are their values necessarily
>>  different (regardless of how they print, or act
>>  when used in an expression)?
>
> No.  See above Q. about int(3).

I now think this answer is yes.  See above Q. about int(3). :-)

>> * What if they aren't unrelated but one is a sub-
>>  class of the other?
>
> Easier no than above.

Yes, I agree no. :-)

>> * Can one completely hide an object's value by
>>  overriding methods?
>
> You tell me ;-)

My guess is no.  For example, if I try to make int that
appears to be 1 + its "real" value:

class myInt (int):
    def __repr__ (self): return int.__repr__(self + 0)
    def __str__ (self): return int.__str__(self + 0)
    def __add__ (self, x):  return int.__add__(self, x + 1)
    def __radd__ (self, x): return int.__add__(self, x + 1)
    def __sub__ (self, x):  return int.__sub__(self, x - 1)
    def __rsub__ (self, x): return int.__sub__(self, x - 1)
    ...etc...

At first it seems to work:

>>> a = myInt(3)
>>> a
4
>>> a + 3
7
>>> 2 - a
-2

But
>>> 5.0 + a
8.0

:-(

> Do you have an example that you were thinking of?

Nothing specific.  I was trying to see if one can
separate the behavior of objects from whatever it
is that constitutes value.  The example above conveys
to me at least that value and behavior *can* be
separated -- even if one could completely hide the
"real" value of an object, one can still view it
as having a real value, and it's apparent value as
something produced by it's behavior.

>> * Can two objects have the same value, even if the
>>  methods of one have been overridden to hide it's
>>  value as completely as possible?
>>
>> I wonder if all values come, directly or indirectly,
>> from "valued objects" created in the C-API?
>
> CPython creates objects with values in C functions.  I presume most are
> exposed in the API.  But my definition is intentionally not specific to
> any implementation.

OK, s/C-API/implementation/

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

Good, I am not chasing a chimera.

>> Leaving behind only state and behavior?
>
> State is a choice amoung possible states, which is to say, information.
> Behavior is determined by class,

Here is my (tentative) concept of value.  I will
give a wordy version and leave a clear, concise
definition to later, or someone else, whichever
occurs first. :-)

Some builtin[1] objects have a value.
A value is a "hidden" piece of data in an object
that is not directly accessible from the Python
language; access to an object's value is provided
only through methods of the object's class.  The
object's methods can (and usually will) make use
of the object's value when producing an object
to return or changing the object's state or value.

It is not possible to define a class in Python
that provides its objects with a value unless
that class is derived from a builtin class that
provides a value.[3]

If this in not an inaccurate description of "value"
it clears up several points of confusion for me:
* No need to worry about what the value of object() is.
  (it has no value.)
* No need to worry about whether expressions return
  values.  (They don't, they always return (references
  to) objects.)
* Where do values come from? (They are created/modified
  by methods of builtin classes and are otherwise not
  directly accessible.)
* How can I find an object's value (if I don't believe
  .str(), .repr(), etc)?  Use gdb. :-)

Notes:

[1] "builtin" is not the right word, but I'm not sure
what is.  I mean, in C-Python, an object created
using the C-API, rather than purely in Python.  This
includes true builtin objects, as well as objects
created in C extensions in stdlib and 3rd-party
extensions.  How to express the distinction
between classes that are or can be defined purely
in Python and those that aren't (can't), in an
implementation independent way, I don't know.
(I presume that in PyPy, everything is defined
in Python.)

[2] I wrote things like "... is not directly accessible"
and "is not possible to...".  That is true for C-Python
but other implementations could violate those statements.
So they probably should be rewritten to "... need not
be directly accessible", "need not be possible to...",
etc.

[3] For rhetorical purposes I am writing factually.  In
reality I am not certain of most of what I've written.
I'm sure mistakes will not go uncorrected and view
this thread as a learning exercise.



More information about the Python-list mailing list