Finding the instance reference of an object

D

Derek Martin

I don't see a difference between a "null value" and not having a value.
[...]
It wasn't until the fifth century C.E. that Indian mathematicians
invented the concept of zero, and it took many centuries for the
idea to get to Europe via the Arabs.

I think he meant None... Or at least, I personally see a distinction
between zero and None (and so do the Python docs). Zero is a value,
whereas None is specifically intended to denote the lack of any value.
I would, FWIW, only make such a distinction in the context of a
computer program... Clearly in mathematics and elsewhere, zero is the
lack of a value (it is the value of nothingness).
"The value of the object is the number of sheep in the paddock, unless
the number of sheep is zero, in which case the object has no value..."
which is needlessly complicated.

For conversation, yes... but technically correct.
I say that 0 is a perfectly fine value. So is None, [], {}, and any other
null-value. I recommend you don't complicate and confuse matters by
trying to treat them differently.
http://www.python.org/doc/1.5.2/api/noneObject.html

7.1.2 The None Object

PyObject * Py_None
The Python None object, denoting lack of value. This object has no
methods.
That won't work you know.

Perhaps not, but it illustrates the point. This *does* work:
.... def __init__(self, val):
.... int.__init__(val)
.... self.foo = None
.... True

So, your description of value is not consistent with Python's
behavior... Python says the two objects I just created have the same
value. But by your definition, they don't. One of you is wrong... ;-)
That depends on whether the existence of foo makes a difference to you or
not. Consider pickle. Since pickle can't predict what aspects of the
object are important, it must treat *everything* as significant, and
pickle will absolutely treat a and b as having different values.

I don't think that's clear... pickle will treat a and b as having
different *data*... For what it's worth, I think the statement in
the language reference that all objects have a type, an ID, and a
value is quite a poor choice of words. Back in 2000, Frederik Lundh
put it much more accurately, I think:

http://effbot.org/zone/python-objects.htm

I think it's up for debate whether the value of attribute of an object
is part of the object's value, if that attribute can never be the
evaluated value of the object itself in an expression -- though only
because it's a semantic argument, and the semantics haven't been
defined. I don't think choosing to say that it is or isn't makes
any practical difference, at all.
But other functions may have weaker constraints. Consider sum([a, b]).
The function sum makes no promises that it will return the same type as
it's arguments. Since, *for the purposes of addition*, the foo attribute
has no significance, sum() makes no promise whether the sum of a and b
will include the foo attribute. In fact it does not. As far as addition
is concerned, a and b have the same value, and the foo attribute is lost.

You seem to be making my point, that the value of an object is
context-specific...

Both of these suggestions are clearly problematical, as when used in
an expression, an object can (and usually does) evaluate to some value
for the purpose of evaluating the expression, and that value may be an
attribute of the class, depending on what we decided is the right
answer to the question above.
I see you are still insisting that value is something that objects
"have" rather than "are".

This falls down, say, for a date object which has the value of the
string representation of the date when printed, and a numeric value
(or some other time object) when used in other expressions, both from
a philisophical and practical standpoint.

Furthermore it falls down semantically; an object has parts that are
not part of its value, and therefore the value and the object can not
be the same. The value is merely one attribute (natural language, not
Python definition) of the object.

[...]
In other words: the value of an expression is the object that the
expression evaluates to.

So too is the value of an object. :)

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


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFJH+QVdjdlQoHP510RAruVAKCrSbpcmKEUsMRHdSyWpDhsLqf1rACgpbaA
BJLW6Tp8ZHy/8Rg701doChg=
=04BU
-----END PGP SIGNATURE-----
 
D

Derek Martin

I believe that the language reference says that objects have an identity,
a type and state, but I'm too lazy too look it up. I'd be happy with that
definition.

They do indeed say value, not state. As I said in a different
message, I'd agree that it's not a very clear definition.
I didn't say it was very useful. As far as I'm concerned, asking what the
value of an object is is not a useful question.

Now we agree. :)
Nonsense.

It's wrong to say *solely*, but the value of x==y does indeed depend
on the behavior of the methods.
I think the value of x is "a thing which claims to be equal to
everything on Tuesdays, and equal to nothing every other day".

That isn't its *VALUE* -- it's its *IDENTITY*. My weight is not my
identity... but in a certain context, it could be considered my value.

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


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFJH+fddjdlQoHP510RAqP8AJ9DM4KKrTutkXgON66eH7Bf6FP8sACghak3
z3CqYb8IN9nsxmPYa/5sl3U=
=J2Jc
-----END PGP SIGNATURE-----
 
A

Arnaud Delobelle

Derek Martin said:
Why does it need to be defined in the Python docs? Is this really
even an important question to answer? Are you unable to write correct
functional programs in Python without having it answered? I suspect
it's not an issue...

Let's assume for the moment that it is, though. The term "value"
already has a meaning... the one ascribed to it by its use in natural
language. One on-line dictionary includes this among its definitions:

magnitude; quantity; number represented by a figure, symbol, or the
like: the value of an angle; the value of x; the value of a sum.

It seems clear that this, or something extremely close to this, is
what is meant in the Python docs by the unqualified use of the term.

I reiterate that IMO the 'value' of an object is not really a useful
concept.

E.g. think of the integer 3. It has a representation ('3'), it compares
to other objects (via int.__eq__, int.__lt__, etc), you can perform
arithmetic operations on it (via int.__add__, int.__sub__, etc), etc.
What more would you want to know about it?

[...]
If you like, you could think of the value of an object as the set of
all possible values to which the object may evaluate in every possible
context, given a particular state of the object.

This definition looks a bit circular to me ;)
 
D

Derek Martin

[...]
If you like, you could think of the value of an object as the set of
all possible values to which the object may evaluate in every possible
context, given a particular state of the object.

This definition looks a bit circular to me ;)

Why, because it has the word "value" in the definition? It's not
circular. The thing being defined is "value of an object". The word
"value" has a pre-existing well-understood natural language definition.

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


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFJH+rOdjdlQoHP510RAnZQAJ4yeOyjlp+CEbQ/mnARar1nK+IIKACdERYi
blVA42bmuDnDwmcBNcBPMno=
=YY5A
-----END PGP SIGNATURE-----
 
A

Arnaud Delobelle

Derek Martin said:
I think he meant None... Or at least, I personally see a distinction
between zero and None (and so do the Python docs). Zero is a value,
whereas None is specifically intended to denote the lack of any value.

None is an 'value' which is intended to denote the absence of any
'value' *other than None*.
I would, FWIW, only make such a distinction in the context of a
computer program... Clearly in mathematics and elsewhere, zero is the
lack of a value (it is the value of nothingness).

I would like to have a word with your maths teacher! There are plenty
of uses for 0, most of which are unrelated to 'nothingess'. E.g. 0 is
*greater* than -1 so it must be something.
 
S

Steven D'Aprano

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?


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


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.


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?


Sorry, I disagree.


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.


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

Steven D'Aprano

* 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.
[...]
It wasn't until the fifth century C.E. that Indian mathematicians
invented the concept of zero, and it took many centuries for the idea
to get to Europe via the Arabs.

I think he meant None... Or at least, I personally see a distinction
between zero and None (and so do the Python docs).

Of course zero is different from None. For starters, you can't add 1 to
None.

Zero is a value,

Yes it is.
whereas None is specifically intended to denote the lack of any value.

None is intended to be *interpreted* by the programmer as the lack of any
other value. That's what the null object pattern is. MySql has a Null, C
has null pointers, Pascal has the nil pointer, Python has None, integer
mathematics has 0, matrix mathematics has any number of identity matrices
under addition, the ASCII character set has nul... in some older
programming frameworks, numbers like 9999 or -1 are used. (I remember a
bug in "Arrow Accounting" that occurred because empty integer fields were
set to 99 or similar.)

I
would, FWIW, only make such a distinction in the context of a computer
program... Clearly in mathematics and elsewhere, zero is the lack of a
value (it is the value of nothingness).

Contradicting your claim above, not to mention about five hundred years
of European mathematics and about 1500 years of Indian mathematics.

For conversation, yes... but technically correct.

No, I would say the value of the object is the number of sheep,
regardless of whether that number is 0 or 1 or 99.

I say that 0 is a perfectly fine value. So is None, [], {}, and any
other null-value. I recommend you don't complicate and confuse matters
by trying to treat them differently.
http://www.python.org/doc/1.5.2/api/noneObject.html

7.1.2 The None Object

PyObject * Py_None
The Python None object, denoting lack of value. This object has no
methods.


I would argue that this particular doc is badly worded. Because Python
doesn't have uninitialized variables, programmers need a value to stand
in for "I don't have a real value for this yet". By convention, None is
usually that value, although object() is another reasonable choice, for
when None is needed for something else.

Perhaps not, but it illustrates the point. This *does* work:

... def __init__(self, val):
... int.__init__(val)
... self.foo = None
...
True

So, your description of value is not consistent with Python's
behavior... Python says the two objects I just created have the same
value. But by your definition, they don't. One of you is wrong... ;-)

No, Python says that the two objects are equal. That's not the same thing.

Unicode strings and byte strings are not the same things:
True

Consider also:
False


I don't think that's clear... pickle will treat a and b as having
different *data*...

Define data, and how is it different from value?

For what it's worth, I think the statement in the
language reference that all objects have a type, an ID, and a value is
quite a poor choice of words. Back in 2000, Frederik Lundh put it much
more accurately, I think:

http://effbot.org/zone/python-objects.htm

Yes. For content, you can also say state.


This falls down, say, for a date object which has the value of the
string representation of the date when printed, and a numeric value (or
some other time object) when used in other expressions, both from a
philisophical and practical standpoint.

No, the value of a date object is neither its printable string
representation, nor the implementation-dependent numeric value in seconds.

Furthermore it falls down semantically; an object has parts that are not
part of its value, and therefore the value and the object can not be the
same. The value is merely one attribute (natural language, not Python
definition) of the object.

I don't agree that this necessarily follows. We say that the value of an
symbol is that which the symbol represents. Consider a map, with a little
radioactive symbol representing a nuclear reactor. Note that the same
symbol is used for the 100 megawatt CANDU reactor here, and the 2
megawatt heavy-water research reactor over there: radically different
things but denoted by the same symbol.

If protesters cut down the chainlink fence surrounding the power station,
do we have to gather up all the maps and erase a pixel from the symbol?
How do we identify which pixel represents the fence and which ones
represents the reactor core?

I would answer these questions by saying that for the purposes of the
map, the chainlink fence is unimportant. The size of the reactor is
unimportant. We can use the same symbol for both reactors, despite the
differences, because for the purpose of mapping the only thing that
matters is the nuclear core. we say that, for the purpose of the map, the
two sites have the same value. The fence is like an attribute of the
reactor object, and irrelevant.

But if you're providing security cameras for the site, then the fence is
very important. For that purpose, you can't interpret both reactors the
same. You might have to use a different symbol, say "Reactor 1" and
"Reactor 2", for them, and you would *not* say that Reactor 1 and Reactor
2 have the same value.
 
S

Steve Holden

Steven said:
Good luck. I think you're chasing your own shadow.
Quite. The question naturally arises "Why would one want to?" This is
naturally followed by "How would it help if you did?"

Can't we just get back to programming? If this endless (sigh) discussion
actually helped anybody to understand how Python worked I could
sympathize with it.

regards
Steve
 
S

Steve Holden

Steven said:
Good luck. I think you're chasing your own shadow.
Quite. The question naturally arises "Why would one want to?" This is
naturally followed by "How would it help if you did?"

Can't we just get back to programming? If this endless (sigh) discussion
actually helped anybody to understand how Python worked I could
sympathize with it.

regards
Steve
 
S

Steve Holden

Steven said:
* How can I find an object's value (if I don't believe
.str(), .repr(), etc)? Use gdb. :)

I would say the object's value is the value, so if you have the object,
you have its value.
[...]

There's also the question, if you say that an object is different from
its value, of determining what the value's value is ...

regards
Steve
 
R

rurpy

Since many responses to my definition of
value raised similar points, I will try
and respond generally here.

In hindsight, I should not have used the
word "value"; it is far too overloaded with
preexisting semantics for me to have attempted
to redefine it, even if it is the word used
(but not defined) in the Python Reference
Manual.

Let me try again, in a slightly different
way and using slightly different terminology
in the hope we can avoid the fascinating
but basically irrelevant philosophical
digressions into form and ideal, the nature
of nothingness, etc. :)

Suppose I have two objects and want to
know if they are the same or not. They
are distinct objects so I know that their
id()'s are different but that's not what
I'm interested in. Example

class A(object): pass
def __init__ (self): self.foo = 1
class B(object): pass
def __init__ (self): self.foo = 2
a = A()
b = B()

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

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!?
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? Why isn't there a .value attribute or
something holding 2? We look at everything we
can but we can see no difference between the two
objects, nothing that tells us that one is a 2,
and the other a 3.

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

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. "value" is then
what is left: the object's local attributes and
the intrinsic-value described above.

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

For example, you can define the value of None
however you want, but it seems clear that it has
(and needs) no intrinsic-value. Same with object().
I now understand why the only way to describe the
object int(2) is requires using str/repr 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".
Etc...

So, is this point of view any more acceptable?

[*1] I took note of Terry Reedy's point that
a.__add__(b) is really int.__add__ (a, b) but
since the two descriptions are isomorphic at
the level I am discussing, it seemed clearer
to leave class out of it.
 
S

Steve Holden

Since many responses to my definition of
value raised similar points, I will try
and respond generally here.

In hindsight, I should not have used the
word "value"; it is far too overloaded with
preexisting semantics for me to have attempted
to redefine it, even if it is the word used
(but not defined) in the Python Reference
Manual.

Let me try again, in a slightly different
way and using slightly different terminology
in the hope we can avoid the fascinating
but basically irrelevant philosophical
digressions into form and ideal, the nature
of nothingness, etc. :)

Suppose I have two objects and want to
know if they are the same or not. They
are distinct objects so I know that their
id()'s are different but that's not what
I'm interested in. Example

class A(object): pass
def __init__ (self): self.foo = 1
class B(object): pass
def __init__ (self): self.foo = 2
a = A()
b = B()

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

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!?
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? Why isn't there a .value attribute or
something holding 2? We look at everything we
can but we can see no difference between the two
objects, nothing that tells us that one is a 2,
and the other a 3.

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

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. "value" is then
what is left: the object's local attributes and
the intrinsic-value described above.

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

For example, you can define the value of None
however you want, but it seems clear that it has
(and needs) no intrinsic-value. Same with object().

In that case I am not sure why this happens:
False

Since those objects are of the same type, and since they have no
"intrinsic value", it would seem you'd expect them to be equal. But they
aren't, because (in the absence of an explicit equality test method)
equality is tested for by testing for identity.
I now understand why the only way to describe the
object int(2) is requires using str/repr 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".
Etc...

So, is this point of view any more acceptable?
Why not just accept that equality is determined by the __eq__ method
[2]? Python can have objects that don't equal anything, even themselves,
objects that are equal to everything, and all definitions in between. So
"equality" doesn't necessarily mean that the values are the same.

If objects have values that differ from the object itself, then aren't
those values themselves objects? If so, what are the values of those
objects?

regards
Steve
[*1] I took note of Terry Reedy's point that
a.__add__(b) is really int.__add__ (a, b) but
since the two descriptions are isomorphic at
the level I am discussing, it seemed clearer
to leave class out of it.

[2] This is a simplification, since the interpreter will fall back on
other methods in the absence of __eq__.
 
T

Terry Reedy

Steven said:
Of course. It wouldn't be Python if they didn't. However, remember that
objects don't have names.

Actually, Python pretty much does compile away names for function
bodies. (They are replaced by array indexes.) It only needs to
manifest them for locals(). CPython Dis.dis also accesses them, but
that is obviously implementation specific. I suspect that the names are
stored as C char sequences rather than as Python string objects unless
and until the latter are needed for locals().

....
... def __eq__(self, other):
... return True
...
True


The methods of 5 don't even get called.

Why do you say that? As I read the manual, type(left-operand).__eq__ is
called first.
This of course is a special case, because 5 is a built-in,

If true, this would be CPython-specific optimization, not language
definition.
> but in general, the result of x==y depends on *both* x and y.

True. But type(x) gets first crack at the answer.

....
You're assuming that == compares values, which is often a safe
assumption, but not always.

The default is to compare by identity, so assuming otherwise is only
safe when one knows the classes of x and y to over-ride the default.

Terry Jan Reedy
 
R

rurpy

In that case I am not sure why this happens:

False

Who said the equality operator compares values
and that Python guarantees that it will always
return True if the values of its arguments are
the same? You yourself point out below that this
is not true -- one can define "==" any way
one wishes. If you can do so, can't the Python
language developers who implement "==" also do
so? In fact they did do so in this case, they
compare id's.

So the next question is, "why not define value
equality (and implicitly values) to be whatever
"==" says it is"? Well you could I suppose. The
only hard constraints are that it be logically
consistent, and not lead to erroneous conclusions
about how Python works. Soft constraints are that
in be easily understandable, and be intuitive.

I don't know if using "==" would meet the two hard
constraints, but it fails the two soft ones.
The context of the definition of "value" in the
Language Reference is where the basic properties
of objects are being described. Why would one
want to make the definition of objects, the core
concept of Python, dependent on the behavior of
the "==" operator?
Since those objects are of the same type, and since they have no
"intrinsic value", it would seem you'd expect them to be equal. But they
aren't, because (in the absence of an explicit equality test method)
equality is tested for by testing for identity.

I would expect them to be equal, but apparently
Python's designers thought otherwise. :)
The "==" operator is designed to return results
that make the most sense (where sense is a
complicated function in the brains of the Python
developers.) In calculating that return value,
Python need not return true for the "same"
intrinsic values any more than than an object
you define in Python has to.
I now understand why the only way to describe the
object int(2) is requires using str/repr 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".
Etc...

So, is this point of view any more acceptable?
Why not just accept that equality is determined by
the __eq__ method [2]?

I do. But equality is not the same as "same-ness"
[Oh god, here comes another round of philosophical
discussion. :)]
Python can have objects that
don't equal anything, even themselves, objects that
are equal to everything, and all definitions in between.
So "equality" doesn't necessarily mean that the values
are the same.

Right! Which is exactly why equality is not the
right concept for trying to think about, "what are
the basic aspects of an object?" and "what is the
value of an object?".
If objects have values that differ from the object itself, then aren't
those values themselves objects? If so, what are the values of those
objects?

Yes, the intrinsic value of a list object contains
(references to) other objects. But note that I did
not claim to say *what* an instrinsic value was or
what it's value was, only that:
* it exists (in some but not all objects).
* builtin[*3] methods and functions can access
it and use it to decide what they will return.
* that it is not accessible from Python language
directly, only though the behavior of the those
builtin methods/functions.[*4]
* That however you define "value" in the P.L.R.
sense) it must include intrinsic value (if any)
So however P.L.R. "value" is defined, it must be
recursive (i.e. the value of [1, [2, 3]] is different
than [1, [2, 4]].)

[*3] Again, I do not have a good term for this but
mean code that is part of the implementation: for
C-Python that would be C-API code that can directly
access an object's implementation.

[*4] That should probably be "may not be accessible..."
since I could imagine an implementation like PyPy
representing such "hidden state" using regular Python
objects.
regards
Steve
[*1] I took note of Terry Reedy's point that
a.__add__(b) is really int.__add__ (a, b) but
since the two descriptions are isomorphic at
the level I am discussing, it seemed clearer
to leave class out of it.

[2] This is a simplification, since the interpreter will fall back on
other methods in the absence of __eq__.
 
T

Terry Reedy

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.

What I specifically said is id, class, instance attributes, and private
data. So objects have only one, some only the other, some both, and
some neither. I also noted that the boundary between properties and
instance methods of the class and attributes of the instance is somewhat
flexible.

I think the important point is this. In Python, objects are
self-identifying bundles of information, which is to say, the bundle
includes knowledge of the which universe of possible bundles the object
comes from, where the universe includes a set of operations. This is
sometimes called RTTI -- run-time type information. This is in contrast
to other languages and signal-processors where information
(bit-patterns) is usually *not* self-identifying, but the universe must
be somehow enforced by a compiler or carried in the context. In C, for
instance, most types cannot have RTTI and RTTI is only required for
unions. Programmers can give structs a type field and that is how
CPython implements PyObjects.

Terry Jan Reedy
 
R

rurpy

This one is easy - its obviously the value that is returned when the value
is returned when you call for the value that you are interested in, unless
you are interested in the bare value, in which case its the value that is
returned.

Except of course, values are *never* returned,
only objects. This is why the concept of an object's
intrinsic value is important. I now understand
that at some point when chasing values, you will
eventually[*1] encounter an object with no intrinsic
value or one for which you have to rely on repr()
to tell you its value; there is no other way to
examine it from the "outside" since (in C-Python)
its value in in a form only C-level code can
understand.

[*1] Excluding circularly linked chains of values
of course.
 
H

Hendrik van Rooyen

Steve Holden said:
There's also the question, if you say that an object is different from
its value, of determining what the value's value is ...

This one is easy - its obviously the value that is returned when the value
is returned when you call for the value that you are interested in, unless
you are interested in the bare value, in which case its the value that is
returned.

I am beginning to suspect that Steven de'A is hammering away at this
to take his mind off the recent cricket game between his country's team
and India. Anything is better than contemplating that. It was enough to
shake one's faith in Southern Supremacy...

:)

- Hendrik
 
H

Hendrik van Rooyen

Terry Reedy said:
I think the important point is this. In Python, objects are
self-identifying bundles of information, which is to say, the bundle
includes knowledge of the which universe of possible bundles the object
comes from, where the universe includes a set of operations. This is
sometimes called RTTI -- run-time type information. This is in contrast
to other languages and signal-processors where information
(bit-patterns) is usually *not* self-identifying, but the universe must
be somehow enforced by a compiler or carried in the context.

This is an important distinction, and it goes even deeper - in some
low level code, the "organisation" consists solely of a priori knowledge
in the mind of the assembler or C programmer - that is also why it is so
difficult to understand machine code - the individual instructions may
be well defined, but because there is no obvious context, it is hard
to figure out what the original programmer's intentions were.
In C, for
instance, most types cannot have RTTI and RTTI is only required for
unions. Programmers can give structs a type field and that is how
CPython implements PyObjects.

Yes, and for some objects, part of that struct is the piece that is
effectively the "value" field, and the content of that is what the
value is.

And here one is faced with the same problem as I pointed to above -
if you do not have access to the struct definition (which you
don't have at run time), its kind of difficult to figure out where
the value is, and you can only access it via the public methods
supplied, if any.

- Hendrik
 
C

Craig Allen

* Do all objects have values? (Ignore the Python
I don't see a difference between a "null value"
and not having a value.

I think the difference is concrete... an uninitialized variable in C
has no value, I'd say, because the value it will have is
indeterminate, it will be whatever happens to be sitting at that
location in memory, inconsistent. If that variable is initialized to
some value representing "none", like NULL, then it has a consistent
value of "none". There is no way to have an uninitialized variable in
python, so they are always consistently set, so they always have
values.

?
 
A

Aaron Brady

I think the difference is concrete... an uninitialized variable in C
has no value, I'd say, because the value it will have is
indeterminate, it will be whatever happens to be sitting at that
location in memory, inconsistent.  If that variable is initialized to
some value representing "none", like NULL, then it has a consistent
value of "none".  There is no way to have an uninitialized variable in
python, so they are always consistently set, so they always have
values.

?

If he was dying, he wouldn't have bothered to carve 'Aaaauuuggghhhh'.
He'd just say it.

#269 and counting!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top