Explanation of list reference

G

Gregory Ewing

Steven said:
And indeed numpy arrays do share state. Why? No idea. Somebody thought
that it was a good idea. (Not me though...)

Probably because they're often large and people don't
want to incur the overhead of copying them any more
than necessary. So slices are defined to return views
rather than independent objects.
 
G

Gregory Ewing

Chris said:
Because everything in Python is an object, and objects always are
handled by their references.

<beginner_thought> So, we have objects... and we have
references to objects... but everything is an object...
so does that mean references are objects too?
</beginner_thought>

This is the kind of trouble you get into when you make
a statement of the form "everything is an X"[1]. When
we say "everything is an object", we don't literally
mean everything, only... well, those things that *are*
objects. Which doesn't really help the beginner much.

[1] Mathematicians tried this. "Everything is a set!"
Yeah, right...
 
C

Chris Angelico

<beginner_thought> So, we have objects... and we have
references to objects... but everything is an object...
so does that mean references are objects too?
</beginner_thought>

References aren't themselves objects. Names, attributes, etc, etc,
etc, all refer to objects. Is it clearer to use the verb "refer"
rather than the noun "reference"?

ChrisA
 
R

Roy Smith

Ben Finney said:
My response: No, because references are not things :)

I've never known a programming beginner to express such a question. Have
you?

You make light of Gregory's point, but he's right. That's exactly the
kind of thing a beginner would get confused about.
 
R

Roy Smith

Chris Angelico said:
References aren't themselves objects. Names, attributes, etc, etc,
etc, all refer to objects. Is it clearer to use the verb "refer"
rather than the noun "reference"?

ChrisA

I know functions are objects, but what about statements? Is the body of
a for loop an object? It is in some languages.
 
C

Chris Angelico

I know functions are objects, but what about statements? Is the body of
a for loop an object? It is in some languages.

And *that* is an extremely fair question. The best explanation I can
come up with is somewhat circular: If it can be named in the code,
it's an object. What that really means is that every object is
first-class (contrast, for instance, C's arrays and functions), but it
doesn't answer the actual question of what's an object and what's not.
But my advice would be to try things in the interactive interpreter.

ChrisA
 
N

Ned Batchelder

Chris said:
Because everything in Python is an object, and objects always are
handled by their references.

<beginner_thought> So, we have objects... and we have
references to objects... but everything is an object...
so does that mean references are objects too?
</beginner_thought>

This is the kind of trouble you get into when you make
a statement of the form "everything is an X"[1]. When
we say "everything is an object", we don't literally
mean everything, only... well, those things that *are*
objects. Which doesn't really help the beginner much.

[1] Mathematicians tried this. "Everything is a set!"
Yeah, right...

The correct statement is "all values are objects", or "all data is
objects". When people mistakenly say "everything is an object", they
are implicitly only thinking about data.

That said, "all data is objects" is really mostly useful in contrast to
other languages where some data is objects and some is not.

I think Ben Finney's point from nearby in this thread is spot on:
there's a huge difference between a beginning programmer and an
experienced programmer new to Python. The latter category is sometimes
the harder to teach, because you have to undo the things they learned
about their earlier language X, but which they mistakenly believe to be
true about all programming languages.
 
C

Chris Angelico

The correct statement is "all values are objects", or "all data is objects".
When people mistakenly say "everything is an object", they are implicitly
only thinking about data.

That said, "all data is objects" is really mostly useful in contrast to
other languages where some data is objects and some is not.

Part of the trouble is that some code is (represented by) objects. A
function is an object, ergo it's data; a module is an object (though
that's different); a class is an object; but no other block of code
is. You can't give a name to a while loop, then pick it up and use it
somewhere else.

x = while input("Guess my number: ")!="42":
print("Wrong number, try again.")

So a while loop isn't data. But wrap it in a function and suddenly it is:

def x():
while input("Guess my number: ")!="42":
print("Wrong number, try again.")

y = x
func(x)
etc

So when does code become data? When it's represented by an object.
What's an object and what's not? Data is objects, non-data is not. And
we're back to being circular again. (Does this mean we're having a
circular discussion about circular definitions?)

ChrisA
 
R

Roy Smith

Chris Angelico said:
Part of the trouble is that some code is (represented by) objects. A
function is an object, ergo it's data; a module is an object (though
that's different); a class is an object; but no other block of code
is.
Lambda?

So when does code become data? When it's represented by an object.

OK, now take somebody who knows lisp and try to explain to him or her
why Python's eval() doesn't mean data is code. Yeah, I know that's
pushing things a bit, but I'm trying to point out that people come into
things with pre-conceived notions that are hard to shake (the psychology
of learning people would call this the Law of Primacy).
 
R

Rustom Mody

Chris Angelico wrote:
OK, now take somebody who knows lisp and try to explain to him or her
why Python's eval() doesn't mean data is code. Yeah, I know that's
pushing things a bit, but I'm trying to point out that people come into
things with pre-conceived notions that are hard to shake (the psychology
of learning people would call this the Law of Primacy).

More true than you (probably) know.
No Ive not seen a newcomer to python who is an old hand at lisp*

What Ive seen is:
25 years ago a 'newcomer' -- like all python objects are objects -- was
a newcomer. One of the things I learnt early was that kids were terrified
of a beastie that has two modes -- one in which it beeps and the other
in which it corrupts the file -- also called 'vi.' Add to that C and pointers
and all that and it was just too much. So my first assignment was not
programming but just to type a poem.

Nowadays the 'newcomers' come with half a dozen computers -- including the
phones in their pockets. They know all sorts of technologies that I dont
-- Whats a raspberry-pi or an xbox? I frankly dont know more than the names
All of them seem to use their phones more savvily than I do!

So I cannot even effectively evaluate what percentage of their
knowledge is ok, what confused and what balderdash.

No -- a clean slate is not a realistic luxury in 2014.


* with the exception of yours truly 12 years ago
 
S

Steven D'Aprano

As far as "x is None" is concerned, a key piece of information is
presented on <URL: http://docs.python.org/3.2/library/constants.html>:

None
The sole value of the type NoneType.
^^^^

Sole, adj. "being the only one; single and isolated from others", e.g.
"the sole heir", "the sole example".

In plain English, None is the sole (only, single) instance of its type.
In computer science jargon, None is a singleton.

Thus, there might still be a nagging concern that a second NoneType
object x such that

x == None and x is not None

could crop up (from native code, perhaps).

If that were possible, then None would not be the sole instance of its
type. Since None is documented as being a singleton, that would be a bad
bug.
 
S

Steven D'Aprano

Probably because they're often large and people don't want to incur the
overhead of copying them any more than necessary. So slices are defined
to return views rather than independent objects.

I don't have a problem with slices returning views. But they should claim
to be views, not claim to be arrays:


py> from numpy import array
py> a = array([1, 2, 3, 4])
py> b = a[:]
py> type(a) is type(b)
True
py> b[1] = 99
py> a
array([ 1, 99, 3, 4])


You can do this to distinguish the two cases:

py> a.base
py> b.base is a
True

but I think a dedicated array_view type would have be better.
 
S

Steven D'Aprano

<beginner_thought> So, we have objects... and we have references to
objects... but everything is an object... so does that mean references
are objects too? </beginner_thought>

Every *thing* is an object. References aren't *things*. An analogy: there
is no thing "Greg Ewing" which is independent of you, there is you, the
thing with an independent existence, and then there is the reference (or
name), "Greg Ewing", a label for you.

But perhaps it is better to say that all *values* are objects.

This is the kind of trouble you get into when you make a statement of
the form "everything is an X"[1]. When we say "everything is an object",
we don't literally mean everything, only... well, those things that
*are* objects. Which doesn't really help the beginner much.

I don't believe that in Python there are any *things* (values) which
aren't objects. Even classes and exceptions are values. That's not the
case in all languages. In Java, you have objects, and you have unboxed
(native) types, and you have classes which aren't values at all. (Or at
least, not first-class values.)


So before you ask: for-loops aren't things (values). Neither are while-
loops, try...except blocks, pass statements, del statements, etc. Nor are
names and other references -- I believe that there is a practice in
certain areas of computer science to call them "l-values", which despite
the name are not values at all -- at least not in Python. Apart from
binding and unbinding:

ref = something()
del ref

which are somewhat special, you can't perform computations on
*references*, only on the things (values) which references refer to.

Contrast this to a hypothetical language which allowed you do perform
computations on references, say using a special ! operator:

# given
x = 23
XY = 42
# then
print (!x+"Y")

would print 42. The expression !x+"Y" operates on the reference itself,
and then print operates on the value referred to by that new reference.

[1] Mathematicians tried this. "Everything is a set!" Yeah, right...

No, that's okay. You only get into trouble when you have self-referential
sets, like "the set of all sets that don't contain themselves".
 
S

Steven D'Aprano

You make light of Gregory's point, but he's right. That's exactly the
kind of thing a beginner would get confused about.


I take it that you haven't spent much time around beginners? Perhaps you
should spend some time on the "tutor" mailing list. If you do, you will
see very few abstract or philosophical questions such as whether
references are themselves things or what identity means. But you will
find plenty of questions about:

- "Will you do my homework for me?"

- "What's this syntax error mean?" (very rarely with the syntax
error actually shown)

- confusion about the fundamentals of sequential algorithms, e.g.
asking why this loop always prints the same value forever:

var = random.randint(1, 10)
while var != 10:
print(var)

and similar sorts of *concrete* problems.

Just about the only abstract question that I've seen from beginners is
the question "What's object oriented programming?" In my experience,
people don't start asking abstract questions until they've been
programming for a few years.
 
C

Chris Angelico

So before you ask: for-loops aren't things (values). Neither are while-
loops, try...except blocks, pass statements, del statements, etc. Nor are
names and other references -- I believe that there is a practice in
certain areas of computer science to call them "l-values", which despite
the name are not values at all -- at least not in Python.

Usually an l-value is something that can go on the left side of
assignment, and an r-value is something that can go on the right side
of assignment. (In most languages, every l-value is also an r-value,
by definition.)

In C, for instance, any simple variable is an l-value, except for
those that are constants (you can't assign to an array). A
dereferenced pointer is also an l-value, as is a structure element
reference. An expression usually isn't (unless it results in a
dereferenced pointer). C++ adds references. You can always assign to
those (the assignment "happens" to the referred-to "thing").

Python says that these things can be assigned to: names, attributes
(with dot), and items (with square brackets); I think that's it. Those
are Python's l-values. Anything that evaluates to an object reference
is an r-value, with the possible exception of function-local names
that haven't been assigned to (does it count as "not an r-value" if
trying to read it raises an exception?).

Python's statements aren't values at all, and can't be referred to.
(Though some of them, like class and def, do result in values or name
bindings. But you can't refer to the def statement, only to the
function object that it creates.)

ChrisA
 
S

Steven D'Aprano

OK, now take somebody who knows lisp and try to explain to him or her
why Python's eval() doesn't mean data is code. Yeah, I know that's
pushing things a bit, but I'm trying to point out that people come into
things with pre-conceived notions that are hard to shake (the psychology
of learning people would call this the Law of Primacy).


There are ways to treat code as values:

- you can use a string (an object/value) representing source code;

- you can create a code object using compile(), passing it a string;

- you can eval or exec on a string or a code object;

- you can extract bits and pieces of function objects;

and possibly others.

But, and I think this is critical, you can't evaluate source code
directly in Python. You can only do so indirectly, after creating some
sort of object: a string, a code object, a function, etc. There is always
an intermediate step: first, create a string object, then treat it as
code. There's no functionality in Python for taking source code directly
*as source code* and treating it as a value:

function(import this)

doesn't work, because `import this` is not a value that can be passed to
the function. You have to make it a string first:

function("import this")


The Python compiler can check the syntax of actual source code at compile
time, but it can't do anything about mock source code until runtime when
you pass it to exec, eval or compile. That's because until that moment,
it's just a string of characters, not source code.
 
R

Rustom Mody

I take it that you haven't spent much time around beginners? Perhaps you
should spend some time on the "tutor" mailing list. If you do, you will
see very few abstract or philosophical questions such as whether
references are themselves things or what identity means. But you will
find plenty of questions about:
- "Will you do my homework for me?"

Right
And what that 'homework' consists of is determined by the educational
context of the questioner.
'Teacher' is of course a big but hardly exclusive part of that
'Syllabus-setters' (who can be more clueless than teachers) are another
'Other attendant factors' big one being programming language.

Hang out on a Haskell list and you will get questions about
- category theory
- typesystems
- structural induction

and so on and so forth

Does that mean Haskell is better than Python?

That depends on which side of the balance-sheet is plus for you.
For some getting the job done with a minimum of heavy-duty concepts is a plus
For some lots of profound concepts is wonderful

Basic to python philosophy is to get people off to a running start quickly.
If NOT starting until you/your ward have mulled on some profundity is your thing
then python is not for you
 
R

Rotwang

[...]

[1] Mathematicians tried this. "Everything is a set!" Yeah, right...

No, that's okay. You only get into trouble when you have self-referential
sets, like "the set of all sets that don't contain themselves".

Actually there's nothing wrong with self-referential sets per se. For
example set theory with Aczel's anti-foundation axiom instead of the
axiom of foundation is consistent if ZF is; see e.g.

http://en.wikipedia.org/wiki/Non-well-founded_set_theory

The trouble comes not with self-reference, but with unrestricted
comprehension.
 

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

Staff online

Members online

Forum statistics

Threads
474,077
Messages
2,570,569
Members
47,206
Latest member
MalorieSte

Latest Threads

Top