Finding the instance reference of an object

S

Steven D'Aprano

Steven D'Aprano wrote:


Why do you say that? As I read the manual, type(left-operand).__eq__ is
called first.

Ah, I could be confabulating that with arithmetic operators __add__ etc.
It may be that comparisons use a different mechanism:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int.__cmp__(x,y) requires y to be a 'int', not a 'EqualsAll'
 
S

Steven D'Aprano

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.

?

Well said.

I'd even go so far as to say that an uninitialized variable in C has a
random value, unless the compiler prevents you from accessing it. If the
compiler lets you (accidentally, I assume!) do something with an
uninitialized variable, then you're accessing whatever random value it
happens to get.
 
S

Steven D'Aprano

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.

Asking *where* the value is is a completely different question to asking
*what* the value is.

I demonstrated that earlier in this thread, where I implemented the
beginnings of an int-class using unary notation, using a linked list. The
value of the object was encoded by the length of the chain of objects, so
there was no "where" that value was stored. It was distributed over the
entire linked list.
 
A

Antoon Pardon

Here is the definition of call-by-value from the
"Revised Report on the Algorithmic Language Algol 60"
<http://www.masswerk.at/algol60/report.htm>:

4.7.3.1. Value assignment (call by value). All formal parameters quoted in the
value part of the procedure declaration heading are assigned the values (cf.
section 2.8. Values and types) of the corresponding actual parameters, these
assignments being considers as being performed explicitly before entering the
procedure body. The effect is as though an additional block embracing the
procedure body were created in which these assignments were made to variables
local to this fictitious block with types as given in the corresponding
specifications (cf. section 5.4.5).

There you have it -- call by value is offially defined in
terms of assignment. There is no mention in there of copying.

Call by value is officially defined in terms of assignment in
a context where assignments means copying and in a definition
of a specifix language.

You can't lift this part out of the definition of algol 60
and say it applies equally well in languages with different
assignment semantics.

If call by value is defined in terms of assignment regardless
of what the semantics of the assignment is then IMO call by
value is rather useless term and it would be better to talk
about call by copy in the case of C, to make sure one understands
the difference between what happens in C and what happens in
other languages that also have "call by assignment" but behave
very differently.
 
A

Aaron Brady

Call by value is officially defined in terms of assignment in
a context where assignments means copying and in a definition
of a specifix language.

You can't lift this part out of the definition of algol 60
and say it applies equally well in languages with different
assignment semantics.

If call by value is defined in terms of assignment regardless
of what the semantics of the assignment is then IMO call by
value is rather useless term and it would be better to talk
about call by copy in the case of C, to make sure one understands
the difference between what happens in C and what happens in
other languages that also have "call by assignment" but behave
very differently.

I think Joe's argument was, C and Python can both be call-by-value, so
long as Python variables are construed to be pointers. To him,
pointers are easy to understand, even for novices, and the copy
constructor for pointers is trivial.

Otherwise, C and Algol have different definitions of call-by-value,
and while Java might be Algol-call-by-value, Python is not C call-by-
value. So, between C and Algol has majority and which has seniority
claim to the term?
 
S

Steven D'Aprano

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.

It shouldn't need definition, since it already has a perfectly fine
definition in the dictionary. It would only need an alternative
definition if the dictionary one isn't suitable.

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.

Define "the same".

Pick up two bricks from the one batch. They have identical size and shape
and colour, but any two bricks will have slight differences. Are they the
same?


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.

Well, sure, if you care *that much* about potentially trivial aspects. I
have a ten dollar note with a spec of dirt on one corner, and a ten
dollar note with a slightly larger spec of dirt on a different corner.
I'd agree with you that they are not "the same" in every aspect, but
they're the same in every way I care about.

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.

Philosophically, no, not irrelevant. You haven't explicitly defined "the
same" in enough detail to make that call. Perhaps because the objects are
in different locations (different IDs) is enough to make them different,
even if everything else about them is identical.

For example, consider the two electrons around a helium nucleus. They
have the same mass, the same speed, the same spin, the same electric
charge, the same magnetic moment, they even have the same location in
space (technically, the same wave function). They are identical in every
possible way. Are they the same electron, or two different electrons?
What does the question even mean?

My point is that as a philosophical position, identity may or may not
count as "sameness". It depends on the circumstances.


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.

Philosophically, sure, but practically, perhaps not. The foo attribute
may be entirely irrelevant to your purposes, the equivalent of a random
speck of dirt or a slight tear on a ten dollar note.

Luckily, Python doesn't try to guess whether differences are significant
or not. You can override the __eq__ method on classes and choose for
yourself what properties of a class are differences that make a
difference and which are mere markers of no particular concern.

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

That's because you haven't asked the objects themselves if they are the
same. Not every aspect of objects are implemented as attributes.


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?

Of course you do. Just look at the object and you will see it is a 2.


Why isn't
there a .value attribute or something holding 2?

Why should there be a value attribute? Python attributes are just a
particular interface for accessing data. It's not the only possible
interface.

We look at everything we can

You forgot to look at the object as a whole. Consider a pair of trousers.
You're rifling through the pockets of one looking for a coin or a wallet
or some other object to distinguish it from another pair of trousers,
without noticing that one is made of blue cotton and the other is green
spandex.


but we can see no difference between the two objects, nothing
that tells us that one is a 2, and the other a 3.

The objects themselves tell us that they are 2 or 3. They don't need an
extra attribute, and in fact the implementation of int objects don't
allow for extra attributes because they have no __dict__ to store them in.

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

I don't think this is a valuable distinction to make. What's the
intrinsic value of a dict?


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.

Let's not.

The type of an object is a label that tells Python where to look in order
to interpret the object. It is certainly *not* the attributes on the
object:
<type 'int'>


"value" is then what is left: the object's local attributes and
the intrinsic-value described above.

What do you mean by "local attributes"?

Do you mean instance attributes? That's well defined: an attribute is an
instance attribute if it is in obj.__dict__. It is a class attribute if
it is in obj.__class__.__dict__.

(Slots make this a little more complicated in practice, but we can ignore
them for now.)

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 think we gain anything from distinguishing value and intrinsic
value, except confusion.


How do you deal with compound objects. What's the value of [1, 2, 3] if
it isn't "the list consisting of ints 1, 2 and 3"?

And recursive objects?

class Parrot:
def __init__(self):
self.me = self

p = Parrot()

a = []
a.append(a)



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.

Think about lists. The "intrinsic" value of a list is the items in the
list itself, if it is anything, but you have an interface for looking at
them individually:

alist

Here's another problem with your idea of "intrinsic value". Consider a
list. The list object in CPython is an array of cells, containing data.
Some of those cells are in use, some of them are free, but regardless of
whether they are free or in use they still have data in them. (The data
may be obsolete in the case of the free cells. The list object also
includes a cell which records the number of cells in the array, and
another cell recording private information of use to the Python garbage
collector. These cells are not necessarily the same size.

Are they part of the "intrinsic value"? You can't access them via
attributes.

What if we use another implementation of list, say, a linked list? What
if we use PyPy, an implementation of Python in Python, and (for the sake
of the argument) lists are implemented as follows:

class list(object): # untested
def __init__(self, values):
for i, x in enumerate(values):
setattr(self, i, x)

(This would make a lousy implementation. Don't try it!) Does that mean
that the value of [1, 2, 3] depends on the implementation of Python you
create it under?


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

To me, that seems just as silly as arguing that zero is not a number, or
that white pixels are "nothing" and black pixels are "something". Or
maybe they should be the other way around?

None is None. It is what it is, and that is it's value. What *meaning*
you put to that is up to your program. It is a convention, a useful
convention but still merely a convention, that None is used to represent
values which otherwise would be missing, if there could be actual holes
in Python code.

Same with
object(). I now understand why the only way to describe the object
int(2) is requires using str/repr

Not true.
.... print "x has the value two"
.... elif x == 3:
.... print "x has the value three"
....
x has the value three


At no stage did I call str() or repr() on x.

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

Expressions always evaluate to objects (unless they don't return at all).
The value of an expression is the object it evaluates to. What is wrong
with that claim? Why do you believe that we need a more complicated,
convoluted understanding of value? What problem are you trying to solve?
 
A

Antoon Pardon

Since the term was more or less invented by the people
who designed Algol, I thought it would be a good idea to
find out, from as close to the source as possible, what
*they* intended it to mean.

But you didn't try to find out their intention. You just took their
words and applied it in a different context. It isn't at all obvious
that placing their words in a context with different assignment
semantics would preserve their intend.
 
S

Steve Holden

Steven said:
Well said.

I'd even go so far as to say that an uninitialized variable in C has a
random value, unless the compiler prevents you from accessing it. If the
compiler lets you (accidentally, I assume!) do something with an
uninitialized variable, then you're accessing whatever random value it
happens to get.
I think the correct terminology would be "the value of the variable is
undefined", meaning that each implementation is free to use whatever
behavior it likes.

Most C implementations will (I believe) end up with random data in those
variables rather than taking the time to initialize them to some
recognizable value (although some implementations have done that), and
this can be a fruitful source of non-repeatable segmentation faults and
inexplicable behaviors.

The nice thing about Python's ability to create variables on assignment
is that you will either get an UnboundLocalError or a NameError or an
AttributeError exception if you try to access a name that hasn't been
defined. This nicely parallels KeyError and IndexError behavior with
container objects.

regards
Steve
 
R

rurpy

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.

I wrote "I don't see a difference between a "null value"
and not having a value" in the specific context of "what
constitutes an object?" considering the Python Docs
definition of object as identity, type, and value. It
was that "value" (the characteristic of an object that
is left after you have considered id and type), that I
was referring to. I still see no difference between a
"null value" and "has no value" in that context.
Nothing (directly) to do with memory, variables, C,
parameter passing, None, etc.

I realize in hightsight that the word "value" is too strongly
overloaded with pre-existing semantics for many people to
accept it being redefined with a specific meaning in the
limited context of a description of Python objects. And it
was also pretty dumb of me to raise the issue in a contentious
thread about values in parameter passing. Live and learn....
 
T

Terry Reedy

For example, consider the two electrons around a helium nucleus. They
have the same mass, the same speed, the same spin, the same electric
charge, the same magnetic moment, they even have the same location in
space (technically, the same wave function).

By quantum mechanics (Pauli Exclusion principle), this is impossible.
> They are identical in every
possible way. Are they the same electron, or two different electrons?
What does the question even mean?

That you do not understand QM?

Photons, on the other hand, can be identical, hence lasars.

Matter is divided into leptons and bosons, individualists and
communalists. (I believe I have the name right.)


To me, that seems just as silly as arguing that zero is not a number,

To me, that distortion of his (and my) point is silly. 0 partipipates
in numerous integer operations, whereas None participates in no NoneType
operations. (Neither has attributes.) And that is the difference he is
pointing at.

or that white pixels are "nothing" and black pixels are "something".

This is a ridiculous attempt at ridicule;-) Pixels have positions and 1
to 4 graded attributes. Completely different from None.

tjr
 
R

Robert Kern

Terry said:
By quantum mechanics (Pauli Exclusion principle), this is impossible.


That you do not understand QM?

Photons, on the other hand, can be identical, hence lasars.

Matter is divided into leptons and bosons, individualists and
communalists. (I believe I have the name right.)

Fermions and bosons, actually.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
A

Aaron Brady

This is a ridiculous attempt at ridicule;-)  Pixels have positions and 1
to 4 graded attributes.  Completely different from None.

IINM if I'm not mistaken, portions of the retina are most excited in
the dark.

Same means one of two things. Either share an identity (continuity of
form), or high degree of similarity in structure and composition.

On a physical level, the electrical states of bit circuits in memory
are very similar in two "equal" bytes. Low voltage, low voltage, high
voltage.

Outside of the physical, the ideal, there is still such thing as
continuity. We have a memory:

M= { 0: [ 1, 2 ],
1: [ 1, 2 ] }

We can write an operation 'app( M, id, val )', which returns the
memory with the entry at id 'id' appended by 'val'. The bracket
operation ( M[ id ] ) returns the entry of the memory at id 'id'.
app( { 0: [ 1, 2 ], 1: [ 1, 2 ] }, 0, 3 )
{ 0: [ 1, 2, 3 ],
1: [ 1, 2 ] }
[ 1, 2, 3 ]

Immutable types don't even need it. Identity serves no additional
purpose to value. That is, you can pick either tuple ( 1, 2 ), ( 1,
2 ) out of a bag with both in it, and operate.

With side-effects come mutable types, and identity and value diverge.
I think you can make a case that type is an entry in value, leaving
identity and value in general. Then, identity just means, what
original expression an object is continuous with, and value is the
original expression plus subsequent mutations.

Logical matter can be created and destroyed, which clarifies some of
the issues about composition and identity.

Now go away, before I taunt you a second time.
 
R

rurpy

And yet you argue when people try to explain to you that objects don't
*have* values, objects *are* values. Objects have attributes, which are
references to other values. One of an object's attributes is its type.

I am sorry for arguing with you. I hear you
and others saying that the value (in the english
language sense of value) of an object *is* the
object.

But before I address that, I am a little confused
by what you wrote above. Quoting the PLR again,
"Every object has an identity, a type and a value."
I presumed "value" to include attributes. Are you
saying the correct statement in the PLR should have
been, "Every object has an identity, attributes, and
a value"?

The text below refers to identity, type and value
per the PLR, but you can substitute "attributes"
for type without affecting the logic.

Here is why I am having trouble accepting the
explanations you and others have kindly offered
me. If values are objects then the words "object"
and "value" are synonymous, yes? Fine, I can see
that could be a desirable thing. Value is more
natural than object for people coming to Python,
for example.

But if you use the word value synonymously with
object, then the PLR statement that "an object
has identity, type, and value" is the same as "an
object has identity, type, and itself". We know
the object is itself!$B!!(BThat's tautological. So
what is the point of using the term value in the
definition of "object"? You can just say "an object
has identity and type, and we will also use the word
value as a synonmym for object."

Other than cosmetics, the word "value" serves no
purpose and we can replace it with "object" wherever
we use it. E.g. "the result of evaluating an
expression is a value.", "the result of evaluating
an expression is an object". If value is the same
as object, then Python objects have only identity
and type.

But you know that's not true. The types of int(2)
and int(3) are the same. Is the difference in
behavior of the two objects due to their different
identities?! Python knows the object at 0x260FF44
is a "2" object, and the object at 0x260FD60 is a
"3" solely by virtue of their addresses?

Of course not.
I hope you see why I find the "value is object"
to be an unacceptable explanation of Python
objects.
You seem to be hunting for the ineffable
"primitive value" that has no other attributes.
Such a thing doesn't exist.

Sorry to argue again, but I explained (in a
previous post) why I believe such a thing does
exist. Specifically, it is necessary to explain
the difference between the objects int(2) and
int(3). Perhaps if you tell me exactly what
fault you find with that previous explanation
(in light of my problem with "values are objects"
above), I could reevaluate my understanding.
 
S

Steven D'Aprano

By quantum mechanics (Pauli Exclusion principle), this is impossible.

Ah yes, you're right. Oops.

However, my point remains if you consider electrons in two atoms, and
remove the "same location in space".

[...]
To me, that distortion of his (and my) point is silly. 0 partipipates
in numerous integer operations, whereas None participates in no NoneType
operations. (Neither has attributes.) And that is the difference he is
pointing at.

Why do you care about built-in NoneType operations? Why don't we count
the infinite number of useful operations we can do to None that merely
happen to not be built-in to the type?

We can convert None to a bool: bool(None)
We can append it to a list: alist.append(None)
We can convert it to a string: str(None), repr(None)
(In Python 2.6) We can ask how many bytes the None object uses.
We can ask the garbage collector how many objects refer to it:
gc.get_referrers
We can count how many words have been written debating whether or not
None is a value.

and so forth. These operations aren't methods on NoneType but that is not
of any importance. The richness or poverty of methods in a class is
irrelevant.

(I trust that nobody is going to raise yet another irrelevant detail and
argue that since None is immutable, these operations don't actually do
anything *to* None. Ints are immutable too, and nobody argues that int(5)
has no value because operations on it don't do anything to it.)

It is useful and convenient to have "null values" like None, but it isn't
useful to say that None is not a value. What does it gain you, other than
losing the useful ability to say "the value of x is None"?
 
G

Gabriel Genellina

I am sorry for arguing with you. I hear you
and others saying that the value (in the english
language sense of value) of an object *is* the
object.

But before I address that, I am a little confused
by what you wrote above. Quoting the PLR again,
"Every object has an identity, a type and a value."
I presumed "value" to include attributes. Are you
saying the correct statement in the PLR should have
been, "Every object has an identity, attributes, and
a value"?

I'll try to avoid any confusion here. I cannot say what defines a Python
object in a generic way, but I do know what defines a CPython object. That
is, I can talk about the current C implementation.
In CPython, an object is a C struct: PyObject. No more, no less. Most
functions in the CPython API receive, return, or handle PyObject pointers
everywhere. Every object in CPython is represented as a PyObject instance,
and has the following properties:

- An object has *identity*: its memory address, immovable, fixed once the
object is allocated.
- An object has a *type*: its ob_type field (a pointer to the type
object). The type is uniquely defined - no type inference is ever done. It
may be changed after the object was created but only if several
prerequisites are met.
- An object has *state* [or value]: everything else stored in the struct.

The PyObject struct is very small and contains nothing apart from the
ob_type field [1]. So a PyObject instance has no state, there is nothing
more defining it. A PyObject instance just "is": it has only identity and
type, it does not carry any state.

More useful objects are built by extending the PyObject struct at the end
- that is, adding more and more fields. By example, a PyIntObject adds a C
"long" field. That new field is the only difference between a PyIntObject
and a bare PyObject. We can say that a PyIntObject gained some "state":
the integer stored inside that field; some people would like to say "its
value". So, to describe completely a PyIntObject, one has to tell -in
addition to its type and identity- *which* number it contains.

More complex objects are built using the same principle: by example, a
PyFunctionObject contains nine more fields (func_code, func_doc, etc.) in
addition to the bare PyObject. Those additional fields represent the
"state" of the function object, and are required to describe it completely.

Instances of user-defined classes may contain arbitrary attributes; this
is implemented using a dictionary. We refer to this dictionary as the
'__dict__' attribute in Python code, but it is just another field in the
object struct, as anything else. In other words, arbitrary attributes are
also stored (indirectly) in the object struct.

So, at least when one looks at the CPython implementation, things are
rather simple: an object is a struct located at certain address
(determines its identity), has a certain type (a field in the struct) and
has a state (everything else in the struct).

You may want to say "value" instead of "state" in all the above
description, but I think it becomes confusing later.

Expressions: Evaluating an expression yields a result, and that result is
an *object*. One could say "the value of this expression" -- but remember
that it is an *object*, like everything else in Python. If one says
"objects have identity, type and value", one cannot say at the same time
"expressions return a value" because the word "value" has a different
meaning in both sentences.

Calling: Same problem applies to "call-by-value". If one says that objects
*have* a value (that implies that value is *part* of the object), it
itsn't its "value" what is passed when a function call is made. The
*whole* object is passed, not its "value" alone. Saying "call-by-object"
describes more accurately what actually happens.

Conclusion: To avoid any ambiguity, I'd say that "objects have identity,
type, and state" (not value), "expressions evaluate to an object" (again,
not value), and "Python passes arguments to functions using a
call-by-object protocol". Given these terms, even "the value of this
expression" might be acceptable because "value" could not be confused with
any "part" of an object.
Here is why I am having trouble accepting the
explanations you and others have kindly offered
me. If values are objects then the words "object"
and "value" are synonymous, yes? Fine, I can see
that could be a desirable thing. Value is more
natural than object for people coming to Python,
for example.

"state" is more common in OO theory, I think. I'd reserve "value" to any
informal description, and use "state" when refering to "anything the
object carries with itself".
I hope you see why I find the "value is object"
to be an unacceptable explanation of Python
objects.

Me too. I hope the above explanation helps to understand the difference.
It is based on a specific implementation, but I feel that describing what
CPython actually does is easier that talking about abstract concepts.
Perhaps somebody can come with an abstract explanation based on this
concrete examples.

[1] There is another field always present: ob_refcnt, but it should be
considered an implementation detail of the reference counting mechanism.
Additional fields may be present in a debug build of Python.
 
A

Antoon Pardon

But many other language designers, of both static and
dynamic languages, have done just that.
I'm not saying it *has* to be interpreted that way,
just that it *is* very often interpreted that way.
So you can't claim that it's not common usage.

You are changing your argument. In a follow up you
made the point that call by value should be as it
was intended by the writers of the algol 60 report.

Now your falling back to how it is often interpreted.
It is very well possible that it is often interpreted
contrary to how it was intended. And since this
interpretation just as often results in misunderstandings
I don't think it is a usefull interpretation.
 
T

Terry Reedy

Steven said:
Why do you care about built-in NoneType operations?

Because class-specific operations are what make one class, and instances
thereof, different from another. If you don't care about that, fine,
but stop ridiculing those who do. Why do you oppose people
investigating specific differences?
> Why don't we count the infinite number of useful operations
> we can do to None that merely happen to not be built-in to the type?

Everything one can do with None is due to its status as a Python object.
We can convert None to a bool: bool(None)
We can append it to a list: alist.append(None)
We can convert it to a string: str(None), repr(None)
(In Python 2.6) We can ask how many bytes the None object uses.
We can ask the garbage collector how many objects refer to it:
gc.get_referrers
We can count how many words have been written debating whether or not
None is a value.

and so forth. These operations aren't methods on NoneType but that is not
of any importance. The richness or poverty of methods in a class is
irrelevant.

To you, but not to me.
It is useful and convenient to have "null values" like None, but it isn't
useful to say that None is not a value.

I never said that. I said that it has no attributes (other than
__class__) and no private data. In other words, no content, no state.
It is an empty object, just like objects()s, and similar in that to
empty collections.

Terry Jan Reedy
 
D

Douglas Alan

greg said:
Steven D'Aprano wrote:
I don't see anything inherently confusing or misleading
about it. Confusion only arises when some people jump up
and say that it's wrong to use the terms that way, because
it might cause confusion...

Personally, I find this whole debate kind of silly, as it is based on
a completely fallacious either/or dichotomy.

(1) It is unarguably true that Python and Java use a type of
call-by-value. This follows from the standard definition of
call-by-value, and common usage in, for example, the Scheme and
Java communities, etc.

(2) It is also unarguably true that saying that Python or Java use
"call-by-value", and saying nothing more is going to be profoundly
confusing to anyone who is learning these languages.

It's like the difference between

Q. What is a giraffe?

A. A giraffe is a type of animal.

and

Q. What is Greg?

A. Greg is a type of animal.

In both cases, the answers are strictly correct, but in the second
case, the answer is also deeply misleading.

Q. How do we generally solve this problem when speaking?

A. We invent more specific terms and then generally stick to the more
specific terms when the more general terms would be misleading.

I.e.,

Q. What is Greg?

A. Greg is a human being.

and

Q. What type of calling semantics do Python and Java use?

A. Call-by-sharing.

I assert that anyone who does not understand all of the above, is
helping to spread confusion.

|>oug
 
J

Joe Strout

Personally, I find this whole debate kind of silly, as it is based on
a completely fallacious either/or dichotomy.

(1) It is unarguably true that Python and Java use a type of
call-by-value. This follows from the standard definition of
call-by-value, and common usage in, for example, the Scheme and
Java communities, etc.
True.

(2) It is also unarguably true that saying that Python or Java use
"call-by-value", and saying nothing more is going to be profoundly
confusing to anyone who is learning these languages.

Perhaps (unless they've already learned this from one of the other
languages).
Q. How do we generally solve this problem when speaking?

A. We invent more specific terms and then generally stick to the more
specific terms when the more general terms would be misleading.

I.e.,

Q. What is Greg?

A. Greg is a human being.

and

Q. What type of calling semantics do Python and Java use?

A. Call-by-sharing.

Fair enough, but if the questioner then says "WTF is call-by-sharing,"
we should answer "call-by-sharing is the term we prefer for call-by-
value in the case where the value is an object reference (as is always
the case in Python)."
I assert that anyone who does not understand all of the above, is
helping to spread confusion.

I agree.

Best,
- Joe
 
C

Craig Allen

I've just come to the conclusion it's not possible to call functions
in python, to do so is undefined and indeterminate, like dividing by
zero. Henceforth no calling functions for me as clearly it's the
devil's playground.
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top