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



[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...@REMOVE-THIS-
cybersource.com.au> wrote:
On Fri, 14 Nov 2008 22:56:52 -0500, Terry Reedy wrote:
rurpy@xxxxxxxxx wrote:
On Nov 13, 4:53 pm, Terry Reedy wrote:
rurpy@xxxxxxxxx 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 :-)

.



Relevant Pages

  • Re: design a Condition class
    ... def match: ... for exp, target in zip: ... # I let you take care of all error handling... ...
    (comp.lang.python)
  • Re: syntactic sugar buzz
    ... def join; "" end ... Matz hand-crafting the language with the greatest care; ... RAILS ROUTING (new! ... & consulting: Ruby Power and Light, ...
    (comp.lang.ruby)
  • Re: identifying new not inherited methods
    ... I am writing a library in which I need to find the names of methods ... def cmd1(self, args): ... If all you care about is ...
    (comp.lang.python)
  • Re: Cyndy Violette
    ... def in that order, the bottom 3 are interchangeable. ... I don't care what anyone says.  I think Clonie's fuckin' hot. ...
    (rec.gambling.poker)
  • Re: Official definition of call-by-value (Re: Finding the instance reference...)
    ... Python docs or elsewhere, despite the fact that a value is one of the ... we usually don't care about identity: ... But context is important: ... we should be indifferent to whether ...
    (comp.lang.python)

Loading