Discussion:
teaching python variables
Amit Aronovitch
2005-12-02 02:26:52 UTC
Permalink
Meta
====
In this essay I'll try to clearly state some of my ideas about variables in
python and how to teach the subject to students new to programming.

The purpose is mainly to let people respond, so I can find out what
other people
have in mind and see if there are major differences. Specificly, I need
to know
this so I can cooperate with Guy Keren (who is currently instructing the
programming class at Hazor), and anyone else who might be interested in
helping
with preperation of material for this course (for ways to help, see
seperate
posts in the python-IL mailing list, web, and wiki).

I was motivated to write this by some statements in Guy's messages,
which led me
to believe that we have some kind of basic misunderstanding. I might
quote these
below, but please don't take it to mean that this is some kind of flamewar.

The reason this is in english, is to avoid some communication problems
that some
readers of the list seem to have (e.g. problems quoting hebrew text in
replies).
It's posted on the list because it seems to be the most active means of
cooperation regarding the course contents. I might put it on the wiki too,
so I can easily find and reedit it in the future.

I hope that this longish meta paragraph will help to avoid
misunderstandings and
reduce off-topic replies from list members.

References
==========
I'll give relevant links here. Some of the things I discuss below are
already
covered in these links, but I'll still repeat, so people would not have to
chase links.

(1) My mini-article in the python-IL wiki (hebrew, with examples of
common bugs)
http://www.python.org.il/mediawiki/index.php/%D7%91%D7%A4%D7%99%D7%99%D7%AA%D7%95%D7%9F_%D7%90%D7%99%D7%9F_%D7%9E%D7%A9%D7%AA%D7%A0%D7%99%D7%9D
(2) An article by Fredrik Lundh (effbot), which seems to have very close
ideas
(thanks Guy for the link):
http://www.effbot.org/zone/python-objects.htm

About Teaching Programming
==========================
Computer languages are specificly designed for humans to write in. As
such, they
try to hide specific hardware details (CPU registers, virtual memory, etc.).
This is not done for portability only, but to help people express their
algorithm in a way that matches human thinking more closely, leaving out
most
lower level details for the programming environment to fill in.

The commonly accepted paradigm for modern programmer trainings, favors
teaching
third (and up) generation languages first, leaving assembly/machine code
(if
tought at all) to a seperate course. The main argument for this is
obvious: if
the language matches human thinking more closely, it would be easier to
teach
to beginners, and would let the instructor focus on general principles
rather
than computer architecture.

I argue that to take full advantage of this principle, you should make use
of all the specific "detail hidings" offered by the language. This is
done by
avoiding explanations of irrelevant "hidden" details, and using the
language's
more easy to explain human-like concepts.

Python offers the concepts of "names" (which are sometimes called
variables)
and "objects", which match human thinking much closer than the "variable"
concept used by many other languages (as I'll explain below).

The problem is that because python is relatively new, most python
instructors
have a deep background in other languages, so the common concept of variable
(which is much lower level) seems natural to them. As a result, they try
to teach this concept, and explain python variables using it.

As a result:

(a) They resort to low level explanations of memory and pointers, which
is time
consuming and makes the subject seem much more complex than it really is.

(b) The "common" concept of variables is different than the one the language
tries to implement. Thus, variables behave in a way that is slightly
different
than the students would expect. This is worse than being *completely*
different,
because it makes them falsely believe they know what to expect, causing very
confusing bugs.

The "Common" Concept of Variables
=================================
The concept of variables was introduced to "hide" the machine level
details of
memory management, memory access (stored pointers), and address registers.
The concept seems to be a natural evolution from Assembly languages'
"labels".
In Assembly you can give labels to areas in the data segment, and you
can also
define (label) fixed numeric data, which are called constants.
The memory areas marked by the labels are commonly used to store data which
varies during the progress of the program (variable data, as opposed to
constants).
To help managing the above, third generation laguages introduce the
concept of
variables. A variable is a fixed section of memory, which the language
refers
to by using a fixed label - the variable name. To avoid certain bugs, some
languages offer ways to enforce a fixed interperetation (type) of the
binary
data stored in the variable. The stored data, interpeted in the
designated way,
is called the variable's value. You can change the value by changing the
stored
binary data - this is called assignment (assigning a new value to the
variable).
This concept is "more human", because it assigns meaning to the binary
data and
treats it as typed values. However, the "variable" is identified with a
specific
position in memory, and you must understand that in order to understand the
behaviour of assignments.

Human Concepts
==============
The discussion above might seem completely obvious and natural to
experienced
programmers. However, since we are discussing teaching people new to
programming
we have to try to unlearn it and revert to more intuitive "human" concepts.

As Fredrik Lundh puts it "Reset your brain"...

In the world of humans, objects (values) just *exist*. We are not normally
concerned with the way they are represented by binary digits or where these
digits are stored.

However, we can freely give them names. We are fully aware that names
are just
artificial labels, not inherently tied to the object itself.
We might call a bear "Teddy", but if we change his name to "Eddie" we
know it's
still the same bear. Moreover, there is nothing stopping us from deciding to
call our cat "Teddy" (objects have types, names do not). If we do name
the cat
Teddy, we certainly would not expect poor old "formerly Teddy" the bear
to be
"overridden" by the cat.

When we give instructions, they often contain names whose values are
assigned
to specific (and different) objects each time they are executed. For example
a recipe for preparing a salad might say "cut the cucumber". Now, each time
you apply that instruction, "the cucumber" refers to a different object.
We don't have to copy the cucumber to a specific storage location,
overriding
the previous cucumber stored there. Only our interpretation of the label
"the cucumber" changed. If you insist on calling "the cucumber" a
variable, it
would be very wierd to say that "the contents" of the variable changed
("contents" implies a physical storage place), only the variable's
assignment to
a physical object changes. Saying that the variable's value changed might be
inexact, but makes more sense (it's not the object itself that changed,
merely
the choice of which value is assigned to the variable).

Python objects and names behave much the same way as the real-world
concepts
described above. Objects (such as numbers, strings and class instances)
just
exist in their own space. They are strongly typed, but do not have an
inherent
"name". The programmer does not need to think about where they are
stored (when
not needed anymore, the garbage collector might decide to erase them,
but this
is just an implementation detail). Names are merely labels - they don't
have
inherent types, and are not associated with a fixed position in memory.
People commonly refer to python "names" as "variables" (and to the
associated
objects as "values"), but that's only because they take roughly the same
role
as other languages' variables. It does NOT mean they are associated to a
specific memory storage area or that they should have inherent types.

Teaching Python Variables
=========================
Explaining Python variables by using the "common variable concept" might
work
well for experienced programmers of other languages (though it might be a
little confusing - see the examples of common bugs in reference (1)).
But for
people learning Python as first language it could be a strategic mistake.

First of all you mislead the students into thinking that python variables
should behave like other languages' vars do, causing them to produce the
same
bugs mentioned in reference (1).

Second, the common concept of variables, while intuitive to experienced
programmers, is still non-trivial. Using it to explain the much simpler
concept
of python names makes it seem unnecessarily complex and confusing. It
could be
compared to trying to use the CPU's address and data registers to explain C
variables.

Typically, the instructor would say (or imply) something like:

* Variables are named areas of memory storing data of some type.
* Pointers are variables storing memory addresses of other variables.
* Python works by reference. This means that variables are actually
implemented as pointers (i.e. store memory addresses), but the language
does implicit dereference whenever they appear in expressions (i.e.
operations other than assignment work on the area pointed to by the
pointer
rather than the pointer itself).

Note that usually they would not say all of that in the first lesson (as
this is
obviously too complex). Instead they would just develop this mental picture
gradually. They'd start with "named areas of memory", then at some point
they
have to explain stuff like "a=[];b=a;b.append(1);print a,b" and things start
getting complex real fast.

Instead, I propose using the "human concepts" from the start. It should
be much
simpler and much less bug-prone:

* The language allows you to give names to objects.
* You can always assign new names to objects, or reassign old names to
other
objects.

That's about it. The rest is just simple usage of reassignment to specify
algorithms - in much the same way as in the "cut the cucumber" example
above.

When explaining these issues to experienced programmers of other languages,
I try to avoid using the term "variables" altogether, but in the context of
training new programmers, the exact choice of words does not really
matter -
as long as you have the right mental picture. Just say something like:

* We call the names "variables" and the assigned objects "values", naming
things is referred to as "assigning values to variables".

(this is mainly useful because of the reversed semantic hierarchy used when
describing assignment: "give a name to an object" vs "assign a value to a
variable")

Misunderstandings?
==================
As promised, I attach snippets from previous correspondense which made
me think
about presentation of variables in this course. Please note that these were
took completely out of context, so please only refer to the parts
relevant to
python variables.
so i might add a new chapter (between chapters 2 and 3) that discusses
issues such as timing code, "objects are references" (or mutable Vs.
immutable objects), and other general python issues that i'll find to be
repetitive in this mini-book.
When a C programmer talks about references, I instinctively get the mental
picture described above as the way *not* to teach python variables. Also
I don't
see what it's got to do with mutable vs. immutable. misunderstanding?
the effectiveness of these nodes (also, as you might guess, I'm
uncomfortable about node8 - variables).
i'll consider using http://www.effbot.org/zone/python-objects.htm to
modify the variables slide.
however! since this intro is not python-specific, i'm not sure i could do
it here. perhaps i should do it on the meeting in which we talk about
variables (the 3rd meeting).
This one got me excited: at last - seems like this time somebody's gonna
teach
python variables "the right way".

6/11, re: intro lecture
regarding variables - i will need to make it clearer, that the computer
need to store the location of the robot somewhere, and that "somewhere" is
a variable (or several variables).
You certainly would. In "human terms" the robot's location *exists* (so
pythonic
concept would be trivial: let's call the location robot_pos). To explain
common
variables you'll have to explain about computer memory, that the
location needs
to be represented as some byte-sequence and stored in it. You can probably
provide a simpler, less accurate explanation, which 20-years-ago-me would
completely misunderstand (I know, this might be a personal disability of
me). This
made me think that the whole issue of common-style vars might better be
dropped
out of the intro.
i have to talk about variables, because they will need to use it for the
while loops.
i do not want to confuse them with talking about names and references and
the like, until this is needed - and this will happen when i first talk
about lists (which are the first mutable data type we will see in the
lessons. references and names are too abstract and meaningless without an
example of when you copy data NOT by types.
You seem to think that names are more complex than variables. My 2.5
years old
son knows all about names. He's a bright kid, but I don't see him grasping
the notion of variables as storage areas in a computer's memory any time
in the
near future.

I also don't see any place where data is being copied AT ALL before
sequences
are introduced (sequences' [:] and + do copy data while creating a new
object).

Until then we're only in the "name calling" business. Are you referring to
the *pointers* being copied in statements like "a=b"? This is an
implementation
detail that the language hides for you. It does that specificly to be
simpler
to users - you certainly don't have to go into such details.

Data can not be copied "not by type" AT ALL in pure python - that's why
I keep
saying that unlike C, python is strongly typed.
clearer if you use the word 'variables' in this case? "changing a
variable" is more intuitive then "changing a name". we'll emphasize
the issues with mutable Vs. non-mutable variables when we start
teaching about arrays and lists... there's no need to stress it so
early, when the kids don't even have a clue about references...
"references" again... Again I get the impression that you think C variables
are simpler than python variables. Also - here comes "mutable vs.
non-mutable"
again - what's that got to do with anything?
I'll talk about what's intuitive in the other mail...
no, don't, because you have no notion of what's intuitive and what's not.
after you try it with real first-timers in the same environment (a class,
you can't give a private lesson to each kid seperately) - then tell me
what is intuitive _for them_ and what is not.
I was referring to basic stuff, as described in "Human Concepts" above. I
consider myself a fairly regular human being, so I hardly believe these
would be much different for other people.
guy keren
2005-12-03 23:44:13 UTC
Permalink
Post by Amit Aronovitch
Meta
====
In this essay I'll try to clearly state some of my ideas about variables in
python and how to teach the subject to students new to programming.
lets cut the long talks. in order for me to understand what you're trying
to do, i would like you to explain the following scenarios using the
Post by Amit Aronovitch
list1 = [2, 3]
list1[0] = 1
print list1
[1, 3]
Post by Amit Aronovitch
a = 1; b = 2; c = 3
list1 = [a, b, c]
list2 = [b, c]
print list1
[1, 2, 3]
Post by Amit Aronovitch
print list2
[2, 3]
Post by Amit Aronovitch
list1 = [1, 2]
list2 = [3, 4]
mlist_a = [list1, list2]
print mlist_a
[[1, 2], [3, 4]]
Post by Amit Aronovitch
mlist_a[1] = list1
print mlist_a
[[1, 2], [1, 2]]
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
RaeNye
2005-12-03 22:26:36 UTC
Permalink
Can I try?

Please verify that I use the same explanation for each syntactic form (list
constructor, __setitem__, assignment operator).
Also, please see that I refrain from mentioning variables and references.

Hope that'd pour some light,
R.

Scenario 1:
----------------
Post by Amit Aronovitch
list1 = [2, 3]
Let there be a list built up from two elements: the number 2 and the number
3. We call it "list1".
Post by Amit Aronovitch
list1[0] = 1
We change the thing called "list1" (which happens to be the object we
created one sentence ago) by replacing its first element from whatever it
was to the number 1.
Post by Amit Aronovitch
print list1
[1, 3]
Now examine the thing called "list1" - it contains two elements: the first
is the number 1 (since we changed it to be so) and the second is the number
3 (since it didn't change from the time the object was born).

Scenario 2:
----------------
Post by Amit Aronovitch
a = 1; b = 2; c = 3
We name the number 1 "a", the number 2 "b" and the number 3 "c".
Post by Amit Aronovitch
list1 = [a, b, c]
We create a list built up from three elements: the object named "a" (i.e.,
the number 1), the object named "b" (i.e., the number 2) and the object
named "c" (i.e., the number 3). We call it "list1".
Post by Amit Aronovitch
list2 = [b, c]
We create a list built up from two elements: the object named "b" (i.e., the
number 2) and the object named "c" (i.e., the number 3). We call it "list2".
Post by Amit Aronovitch
print list1
[1, 2, 3]
The object named "list1" consists of the number 1, the number 2 and the
number 3. That exactly how it was bulit.
Post by Amit Aronovitch
print list2
[2, 3]
The object named "list2" consists of the number 2 and the number 3. That
exactly how it was bulit.

Scenario 3:
----------------
Post by Amit Aronovitch
list1 = [1, 2]
list2 = [3, 4]
We create two lists, named "list1" and "list2" respectively (with the
obvious content: the number 1 ...)
Post by Amit Aronovitch
mlist_a = [list1, list2]
We create a list built of the object named "list1" and the object named
"list2" (which are the same two lists created above). We call it "mlist_a".
Post by Amit Aronovitch
print mlist_a
[[1, 2], [3, 4]]
Obvious.
Post by Amit Aronovitch
mlist_a[1] = list1
We change the thing called "mlist_a" (which happens to be the object we
created two sentences ago) by replacing its first element to the object
named "list1".
Note that now the object named "mlist_a" contains the same object as both
the first and the seconds element: a list that consists of the number 1 and
the number 2.
Post by Amit Aronovitch
print mlist_a
[[1, 2], [1, 2]]
Obvious, considering the last note.


-----Original Message-----
From: guy keren [mailto:***@actcom.co.il]
Sent: Sunday, December 04, 2005 1:44 AM
To: Amit Aronovitch
Cc: ***@linux.org.il
Subject: Re: teaching python variables
Post by Amit Aronovitch
Meta
====
In this essay I'll try to clearly state some of my ideas about
variables in python and how to teach the subject to students new to
programming.

lets cut the long talks. in order for me to understand what you're trying to
do, i would like you to explain the following scenarios using the terms
Post by Amit Aronovitch
list1 = [2, 3]
list1[0] = 1
print list1
[1, 3]
Post by Amit Aronovitch
a = 1; b = 2; c = 3
list1 = [a, b, c]
list2 = [b, c]
print list1
[1, 2, 3]
Post by Amit Aronovitch
print list2
[2, 3]
Post by Amit Aronovitch
list1 = [1, 2]
list2 = [3, 4]
mlist_a = [list1, list2]
print mlist_a
[[1, 2], [3, 4]]
Post by Amit Aronovitch
mlist_a[1] = list1
print mlist_a
[[1, 2], [1, 2]]


--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
guy keren
2005-12-04 02:19:38 UTC
Permalink
Post by RaeNye
Please verify that I use the same explanation for each syntactic form (list
constructor, __setitem__, assignment operator).
Also, please see that I refrain from mentioning variables and references.
----------------
list1 = [1, 2]
list2 = [3, 4]
We create two lists, named "list1"and "list2" respectively (with the
obvious content: the number 1 ...)
mlist_a = [list1, list2]
We create a list built of the object named "list1" and the object named
"list2" (which are the same two lists created above). We call it "mlist_a".
print mlist_a
[[1, 2], [3, 4]]
Obvious.
mlist_a[1] = list1
We change the thing called "mlist_a" (which happens to be the object we
created two sentences ago) by replacing its first element to the object
named "list1".
Note that now the object named "mlist_a" contains the same object as both
the first and the seconds element: a list that consists of the number 1 and
the number 2.
ok. an object containing the same element twice. you're using the concept
of reference, without using the word reference. to me this sounds like
breaking the rules. otherwise, how can an object contain the same object
twice? does it contain two copies of this object? or perhaps it contains 2
references to the same object?

and then what happens if i go and change list1[0] to be '3'? it changed
twice, didn't it? so the object named mlist_a actually references the
object named list1, right?

can you explain this thing without mentioning the word "reference", as
well as without using the concept "reference"?

note that i didn't even mention things like iterators, slices (which
create a new list containing references to some of the members of an
existing list), etc.

i don't see how references can be avoided (as a concept, not just by not
using the name).
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
RaeNye
2005-12-03 23:47:52 UTC
Permalink
Alas, the *concept* of reference is common to the human mind and human
language!

This sentence is an fine example of it, as it contains references to itself
("this", "it contains") and to the concept of reference ("example of it").

Why don't you complain about the following line of code?
Post by guy keren
a = [1, 1]
It shows the exact same "problem" - how can the number 1 appear twice in the
same list?
Surely you wouldn't even consider the thought that these are different
"instances" of the number 1 (although this might be true in other
programming languages);
Your concept of what a list /is/ should be ready to accept an object
appearing as multiple elements in it.
Post by guy keren
and then what happens if i go and change list1[0] to be '3'? it changed
twice, didn't it? so the object named mlist_a actually references the object
named list1, right?
The whole point is that names are only temporary labels, immediately
replaced by the objects they (currently) stand for.

I don't say the concept of reference is avoidable. I only refuse to present
it as a special thing.
The very same intuitive connection that exists between a name and an object
called by this name, exists in other places as well, e.g., between a
container element and the object that the container contains there (in fact,
considering that global names are just __main__.__dict__.keys(), it *is* the
same connection).

R.

-----Original Message-----
From: guy keren [mailto:***@actcom.co.il]
Sent: Sunday, December 04, 2005 4:20 AM
To: RaeNye
Cc: ***@linux.org.il; 'Amit Aronovitch'
Subject: RE: teaching python variables
Post by guy keren
Please verify that I use the same explanation for each syntactic form
(list constructor, __setitem__, assignment operator).
Also, please see that I refrain from mentioning variables and references.
----------------
list1 = [1, 2]
list2 = [3, 4]
We create two lists, named "list1"and "list2" respectively (with the
obvious content: the number 1 ...)
mlist_a = [list1, list2]
We create a list built of the object named "list1" and the object
named "list2" (which are the same two lists created above). We call it
"mlist_a".
Post by guy keren
print mlist_a
[[1, 2], [3, 4]]
Obvious.
mlist_a[1] = list1
We change the thing called "mlist_a" (which happens to be the object
we created two sentences ago) by replacing its first element to the
object named "list1".
Note that now the object named "mlist_a" contains the same object as
both the first and the seconds element: a list that consists of the
number 1 and the number 2.
ok. an object containing the same element twice. you're using the concept of
reference, without using the word reference. to me this sounds like breaking
the rules. otherwise, how can an object contain the same object twice? does
it contain two copies of this object? or perhaps it contains 2 references to
the same object?

and then what happens if i go and change list1[0] to be '3'? it changed
twice, didn't it? so the object named mlist_a actually references the object
named list1, right?

can you explain this thing without mentioning the word "reference", as well
as without using the concept "reference"?

note that i didn't even mention things like iterators, slices (which create
a new list containing references to some of the members of an existing
list), etc.

i don't see how references can be avoided (as a concept, not just by not
using the name).

--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
guy keren
2005-12-04 22:28:25 UTC
Permalink
Post by RaeNye
Alas, the *concept* of reference is common to the human mind and human
language!
so your initial claim of being able to explain the examples without using
references, is false.

so we now agree that we need to teach two concepts: names and references.

now comes the next issue:

you can change a list.
you can't change a number.
you can't change a string.
you can't change a tuple.

in order to explain this, i will use the 'mutable' Vs. 'immutable' issue.

do you have a way to aovid that?

the rest of what you write is not realy important, except for one point
Post by RaeNye
Why don't you complain about the following line of code?
a = [1, 1]
It shows the exact same "problem" - how can the number 1 appear twice in the
same list?
when a person thinks about the number '1', they do NOT think of it as an
object. thus, they are not surprised to see it used twice in a list. the
concept that even a single number is an object is not something natural -
you don't think of "1+2" as "1.add(2)" (i.e. as an operation of 'add 2' on
the object '1'). you just think of the operationg of adding `1 and 2
together. you only consider it when you learn about languages such as
smalltalk (which started this "everything is an object" concept. in
smalltalk there are no operators. in order to perform addition, you write
something like:

[1 add: 2]

(i.e. send the message 'add:' to the object '1', supplying the object '2'
as a parameter).

since python is not pure about the syntax, we don't need to be pure about
explaining things.
Post by RaeNye
Surely you wouldn't even consider the thought that these are different
"instances" of the number 1 (although this might be true in other
programming languages);
actually - this is exactly what i wold have thought before being taught
programming - that you can use the number 1 here, and there, and i'd not
even bother thinking that they are the same '1'.
Post by RaeNye
Your concept of what a list /is/ should be ready to accept an object
appearing as multiple elements in it.
in other words - references. that's what i wanted to show in the first
place - thanks for helping ;)
Post by RaeNye
I don't say the concept of reference is avoidable. I only refuse to present
it as a special thing.
when you teach programming - everything must be explicit. what you think
is intuitive - is intuitive in a different way to different people.
avoiding talking about something does not make it clear.
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
Amit Aronovitch
2005-12-05 17:45:26 UTC
Permalink
Post by guy keren
Post by RaeNye
Alas, the *concept* of reference is common to the human mind and human
language!
so your initial claim of being able to explain the examples without using
references, is false.
so we now agree that we need to teach two concepts: names and references.
What I call "reference" is implicitly included in most people's (most
non-programmers, at least) understanding of what the word "name" means.

The same thing also appears in other concepts, such as lists. While a
python list does not fully coincide with the daily use of the word, it
almost does. My "physical note with list of items" example in another
post might help explaining the (minor) difference.

You do have to talk about names. You do have to talk about lists (and
probably about dicts and tuples, which are other types involving
references).
Technically you don't HAVE to explain references as a seperate concept,
but it might prove useful (e.g. when explaining the fine details about
lists).

The point is - people DO know about names and it might be easier to
explain references (or list items) by using the example of names than
the other way around.

p.s. : A standalone object implementing the "reference" concept would
coincide with a pointer (actually a weakref is almost exactly that) - I
don't think we should confuse them with these.
Post by guy keren
you can change a list.
you can't change a number.
you can't change a string.
you can't change a tuple.
in order to explain this, i will use the 'mutable' Vs. 'immutable' issue.
So - some objects you can change, some not, some you can change but don't.
(Note that a tuple contains references even though you can't change it).
What's so special about that?
Do you define "immutable" any other way than "object that can't be changed"?

I'd only mention mutability when your'e about to explain about dicts.
You can only use immutable objects as keys for a dictionary. This is a
fact that needs to mentioned, even if you don't explain why.
(the explanation involves considerations of efficiency, and
understanding how dicts are implemented - might be included in the
data-structures reading material, but not strictly necessary for this
course).
Post by guy keren
do you have a way to aovid that?
the rest of what you write is not realy important, except for one point
Post by RaeNye
Why don't you complain about the following line of code?
a = [1, 1]
It shows the exact same "problem" - how can the number 1 appear twice in the
same list?
when a person thinks about the number '1', they do NOT think of it as an
object. thus, they are not surprised to see it used twice in a list. the
concept that even a single number is an object is not something natural -
Depends on how you define object. Common interpretation of the word is
"physical object" like "car", but people do say "abstract object" when
referring to e.g. numbers. In the context of a computer language, a
number is about as physical as a car, so by "python objects" we mean any
kind of data. This might need to be explicitly said.
However, it is completely natural to give names to numbers - "two","my
age", etc. And it's no surprise you can put them in a list. Many people
even have the same phone-number listed more than once in their diary.
Post by guy keren
you don't think of "1+2" as "1.add(2)" (i.e. as an operation of 'add 2' on
the object '1'). you just think of the operationg of adding `1 and 2
together. you only consider it when you learn about languages such as
smalltalk (which started this "everything is an object" concept. in
smalltalk there are no operators. in order to perform addition, you write
[1 add: 2]
(i.e. send the message 'add:' to the object '1', supplying the object '2'
as a parameter).
ahh... touchy point.
Post by guy keren
Post by RaeNye
(1).__add__(2)
3
Now if you insist on using methods exclusively, you might ask: is 1+2
actually "(1).__add__(2)" or "(2).__radd__(1)"?
You quickly get into the following quicksand:
http://www.python.org/doc/2.4.2/ref/coercion-rules.html
As someone who had the unpleasant experience of having to use and
implement such methods, I can tell you that's one big nasty wart in
python (luckily their'e aiming to phase that out towards python3).

I believe that since both operands have symmetric status, the right
thing to do would be to treat the operation as a seperate entity,
somewhat like in C++ "friend T operator+(T first, T second)". Unlike
Java, we do have simple functions in python.
Post by guy keren
since python is not pure about the syntax, we don't need to be pure about
explaining things.
Post by RaeNye
Surely you wouldn't even consider the thought that these are different
"instances" of the number 1 (although this might be true in other
programming languages);
actually - this is exactly what i wold have thought before being taught
programming - that you can use the number 1 here, and there, and i'd not
even bother thinking that they are the same '1'.
If you ever wrote buggy fortran77 code, you might have quickly and
painfuly learned that it's the same instance ;-)
(stepping over constants such as 1 or 0 is a very real and common bug
there, and it can have unbelievably confusing and hard to track results
- I imagine they added some safety measures in fortran90).
Post by guy keren
Post by RaeNye
Your concept of what a list /is/ should be ready to accept an object
appearing as multiple elements in it.
in other words - references. that's what i wanted to show in the first
place - thanks for helping ;)
Post by RaeNye
I don't say the concept of reference is avoidable. I only refuse to present
it as a special thing.
when you teach programming - everything must be explicit. what you think
is intuitive - is intuitive in a different way to different people.
avoiding talking about something does not make it clear.
Different people do have different intuitions about abstract or invented
concepts. That's why I strongly suggest using concrete "daily life"
examples (e.g. for names and for lists. You can use these examples to
extract the common "reference" property inherent in these two concepts).
Nir Soffer
2005-12-03 23:49:58 UTC
Permalink
Here is my version, not using the "variable", but using "reference",
which seem natural.
Post by RaeNye
----------------
list1 = [2, 3]
Let there be a list built up from two elements: the number 2 and the number
3. We call it "list1".
Create a list with two numbers and bind it to the name "list1"
Post by RaeNye
list1
[2, 3]
Post by RaeNye
list1[0] = 1
We change the thing called "list1" (which happens to be the object we
created one sentence ago) by replacing its first element from whatever it
was to the number 1.
Why use "thing"? simply talk about "list1"

Set the first item of list1 to the number 1
Post by RaeNye
print list1
[1, 3]
Now examine the thing called "list1" - it contains two elements: the first
is the number 1 (since we changed it to be so) and the second is the number
3 (since it didn't change from the time the object was born).
We can see that the first item was replaced.
Post by RaeNye
----------------
a = 1; b = 2; c = 3
We name the number 1 "a", the number 2 "b" and the number 3 "c".
This is very confusing - you should not talk about "a" which is a
string!

Create 3 names and bind the numbers 1, 2, and 3 to the names.
Post by RaeNye
list1 = [a, b, c]
We create a list built up from three elements: the object named "a" (i.e.,
the number 1), the object named "b" (i.e., the number 2) and the object
named "c" (i.e., the number 3). We call it "list1".
Create a list containing those numbers.

It can make it more clear to ask: is [a, b, c] equal to [1, 2, 3]?
Post by RaeNye
[a, b, c] == [1, 2, 3]
True

It should be clear that a is NOT an object, its a name, and it is bound
to the object "1" which is a number.
Post by RaeNye
a = 1
type(a)
<type 'int'>
Post by RaeNye
a = 3.14
type(a)
<type 'float'>
Post by RaeNye
a = 'String'
type(a)
<type 'str'>

a is a name, we can bind it to any object.
Post by RaeNye
a = 1
b = 1
a == b
True
Post by RaeNye
a is b
True

Same object can be bound to may names.
Post by RaeNye
list2 = [b, c]
We create a list built up from two elements: the object named "b" (i.e., the
number 2) and the object named "c" (i.e., the number 3). We call it "list2".
Create another list from the same numbers
Post by RaeNye
print list1
[1, 2, 3]
The object named "list1" consists of the number 1, the number 2 and the
number 3. That exactly how it was bulit.
Printing the lists, not much to explain.
Post by RaeNye
print list2
[2, 3]
The object named "list2" consists of the number 2 and the number 3. That
exactly how it was bulit.
Again.
Post by RaeNye
----------------
list1 = [1, 2]
list2 = [3, 4]
We create two lists, named "list1" and "list2" respectively (with the
obvious content: the number 1 ...)
Same as before.
Post by RaeNye
mlist_a = [list1, list2]
We create a list built of the object named "list1" and the object named
"list2" (which are the same two lists created above). We call it "mlist_a".
Why use this strange name "mlist_a"? Instead use:

multiple_lists = [list1, list2]
Post by RaeNye
print mlist_a
[[1, 2], [3, 4]]
Obvious.
mlist_a[1] = list1
We change the thing called "mlist_a" (which happens to be the object we
created two sentences ago) by replacing its first element to the object
named "list1".
Note that now the object named "mlist_a" contains the same object as both
the first and the seconds element: a list that consists of the number 1 and
the number 2.
This is not a good example, because you can show the same thing using
Post by RaeNye
name = 'Foo'
list = [name, name]
list[0]
'Foo'
Post by RaeNye
list[1]
'Foo'
Post by RaeNye
list[0] == list[1]
True
Post by RaeNye
list[0] is list[1]
True

A list contain reference to other objects. The same object can appear
multiple times in the same list.
Post by RaeNye
print mlist_a
[[1, 2], [1, 2]]
Obvious, considering the last note.
But all this code is too dry - better show interesting usage examples
for each Scenario. The student does not have to really understand how
Python works in this stage, a partial and simple "picture" is needed,
the picture may be more complete and correct in the end of the course.

Anyway how you explain things is not the most important thing - its
more important that the students will spend a lot of time with Python,
trying to do simple things, make errors and learn from them.


Best Regards,

Nir Soffer
RaeNye
2005-12-04 00:09:10 UTC
Permalink
Post by Nir Soffer
Why use "thing"? simply talk about "list1"
Set the first item of list1 to the number 1
This is where you bluntly mislead the students.
"list1" is /nothing/ but the object it's currently binded to, and it's ultra
important that they understand this.
Otherwise, they would think the following code doesn't change the object
name "list2", as it only deals with "list1".
Post by Nir Soffer
Post by RaeNye
list1 = [0]
list2 = list1
list1[0] = 100
We name the number 1 "a", the number 2 "b" and the number 3 "c".
This is very confusing - you should not talk about "a" which is a string!
Create 3 names and bind the numbers 1, 2, and 3 to the names.
Come on... I speak english here, not python!
Imagine a bold fontface wherever I use quotation marks.
Post by Nir Soffer
multiple_lists = [list1, list2]
I don't see a problem with Guy's name selection. I consider your suggestion
worse, as the object called "multiple_lists" is, in fact, a single list that
contains two other lists. You might call the outer list "nested_list" or
"outer_list", but "multiple_lists" has nothing to do with the object itself.

-----Original Message-----
From: Nir Soffer [mailto:***@freeshell.org]
Sent: Sunday, December 04, 2005 1:50 AM
To: RaeNye
Cc: 'guy keren'; ***@linux.org.il; 'Amit Aronovitch'
Subject: Re: teaching python variables

Here is my version, not using the "variable", but using "reference", which
seem natural.

<snip>
Nir Soffer
2005-12-04 01:58:27 UTC
Permalink
Post by RaeNye
Post by Nir Soffer
multiple_lists = [list1, list2]
I don't see a problem with Guy's name selection. I consider your suggestion
worse, as the object called "multiple_lists" is, in fact, a single list that
contains two other lists. You might call the outer list "nested_list" or
"outer_list", but "multiple_lists" has nothing to do with the object itself.
"lists" will be a better name. But why the names in this code are so
lousy? because its not a concrete example, its too abstract. Using real
life examples can make everything more clear.

For example, bart simpson downloaded our first game, and lisa created a
Post by RaeNye
Post by Nir Soffer
lisa_scores = [90, 85, 80]
bart_scores = [50, 65]
homer_scores = [] # too stupid to play
marge_scores = [] # too busy
# Lets keep all the scores in one list
Post by RaeNye
Post by Nir Soffer
simpsons_scores[lisa_scores, bart_scores, homer_scores,
marge_scores]

Now we can ask questions about it:

What were lisa scores?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0]
[90, 85, 80]
Post by RaeNye
Post by Nir Soffer
lisa_scores
[90, 85, 80]

they look equal...
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] == lisa_scores
True

They are.

Is it the same list of a copy?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] is lisa_scores
True

This answer the question, what happens when you do list = [foo, bar] -
you create reference to the objects.
Post by RaeNye
Post by Nir Soffer
homer_scores == marge_scores
True
Post by RaeNye
Post by Nir Soffer
homer_scores is marge_scores
False
Post by RaeNye
Post by Nir Soffer
homer_scores.append(10)
simpsons_scores
[[90, 85, 80], [50, 65], [10], []]

homer_scores and simpsons_scores[2] reference the same list object
(which Python manage for us somewhere in the memory)
Post by RaeNye
Post by Nir Soffer
homer_scores.append(11)
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]
Post by RaeNye
Post by Nir Soffer
del lisa_scores
lisa_scores
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'lisa_scores' is not defined

That was evil!
Post by RaeNye
Post by Nir Soffer
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]

F**k! they are still there!? hmm, lisa_scores was not the list, its
only a name, the list is still there. This is exactly what Python told
us just now: "NameError: name 'lisa_scores' is not defined".

lisa fixes the situation
Post by RaeNye
Post by Nir Soffer
lisa_scores = simpsons_scores[0]
lisa_scores
[90, 85, 80]

Now [[90, 85, 80], [50, 65], [10, 11], []] is a lousy way to keep this
kind of data, because we have to remember the order of the family
members. This leads naturally to dicts - because we need it NOW to
write simpler and more readable code.


I hope it helps, It was fun to write :-)


Best Regards,

Nir Soffer
RaeNye
2005-12-04 02:03:44 UTC
Permalink
Now that's a splendid example.

The previous Guy-Amit discussion was on a somewhat higher level (not
actually relating to the specific ongoing course), but surely when teaching
the kids it's better to use this kind of examples.

R.

-----Original Message-----
From: Nir Soffer [mailto:***@freeshell.org]
Sent: Sunday, December 04, 2005 3:58 AM
To: RaeNye
Cc: Python User Group
Subject: Re: teaching python variables
Post by RaeNye
Post by Nir Soffer
multiple_lists = [list1, list2]
I don't see a problem with Guy's name selection. I consider your
suggestion worse, as the object called "multiple_lists" is, in fact, a
single list that contains two other lists. You might call the outer
list "nested_list"
or
"outer_list", but "multiple_lists" has nothing to do with the object itself.
"lists" will be a better name. But why the names in this code are so lousy?
because its not a concrete example, its too abstract. Using real life
examples can make everything more clear.

For example, bart simpson downloaded our first game, and lisa created a list
Post by RaeNye
Post by Nir Soffer
lisa_scores = [90, 85, 80]
bart_scores = [50, 65]
homer_scores = [] # too stupid to play >>> marge_scores = [] # too
busy

# Lets keep all the scores in one list
Post by RaeNye
Post by Nir Soffer
simpsons_scores[lisa_scores, bart_scores, homer_scores, marge_scores]
Now we can ask questions about it:

What were lisa scores?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0]
[90, 85, 80]
Post by RaeNye
Post by Nir Soffer
lisa_scores
[90, 85, 80]

they look equal...
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] == lisa_scores
True

They are.

Is it the same list of a copy?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] is lisa_scores
True

This answer the question, what happens when you do list = [foo, bar] - you
create reference to the objects.
Post by RaeNye
Post by Nir Soffer
homer_scores == marge_scores
True
Post by RaeNye
Post by Nir Soffer
homer_scores is marge_scores
False
Post by RaeNye
Post by Nir Soffer
homer_scores.append(10)
simpsons_scores
[[90, 85, 80], [50, 65], [10], []]

homer_scores and simpsons_scores[2] reference the same list object (which
Python manage for us somewhere in the memory)
Post by RaeNye
Post by Nir Soffer
homer_scores.append(11)
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]
Post by RaeNye
Post by Nir Soffer
del lisa_scores
lisa_scores
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'lisa_scores' is not defined

That was evil!
Post by RaeNye
Post by Nir Soffer
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]

F**k! they are still there!? hmm, lisa_scores was not the list, its only a
name, the list is still there. This is exactly what Python told us just now:
"NameError: name 'lisa_scores' is not defined".

lisa fixes the situation
Post by RaeNye
Post by Nir Soffer
lisa_scores = simpsons_scores[0]
lisa_scores
[90, 85, 80]

Now [[90, 85, 80], [50, 65], [10, 11], []] is a lousy way to keep this kind
of data, because we have to remember the order of the family members. This
leads naturally to dicts - because we need it NOW to write simpler and more
readable code.


I hope it helps, It was fun to write :-)


Best Regards,

Nir Soffer
guy keren
2005-12-04 22:30:41 UTC
Permalink
good, good. i think we have a candidate for writing the slides for meeting
11 (even thought i already spoke with amit about doing it - he might agree
to switch ;) ).

what sais you?

--guy
Post by Nir Soffer
Post by RaeNye
Post by Nir Soffer
multiple_lists = [list1, list2]
I don't see a problem with Guy's name selection. I consider your suggestion
worse, as the object called "multiple_lists" is, in fact, a single list that
contains two other lists. You might call the outer list "nested_list" or
"outer_list", but "multiple_lists" has nothing to do with the object itself.
"lists" will be a better name. But why the names in this code are so
lousy? because its not a concrete example, its too abstract. Using real
life examples can make everything more clear.
For example, bart simpson downloaded our first game, and lisa created a
Post by RaeNye
Post by Nir Soffer
lisa_scores = [90, 85, 80]
bart_scores = [50, 65]
homer_scores = [] # too stupid to play
marge_scores = [] # too busy
# Lets keep all the scores in one list
Post by RaeNye
Post by Nir Soffer
simpsons_scores[lisa_scores, bart_scores, homer_scores,
marge_scores]
What were lisa scores?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0]
[90, 85, 80]
Post by RaeNye
Post by Nir Soffer
lisa_scores
[90, 85, 80]
they look equal...
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] == lisa_scores
True
They are.
Is it the samelist of a copy?
Post by RaeNye
Post by Nir Soffer
simpsons_scores[0] is lisa_scores
True
This answer the question, what happens when you do list = [foo, bar] -
you create reference to the objects.
Post by RaeNye
Post by Nir Soffer
homer_scores== marge_scores
True
Post by RaeNye
Post by Nir Soffer
homer_scores is marge_scores
False
Post by RaeNye
Post by Nir Soffer
homer_scores.append(10)
simpsons_scores
[[90, 85, 80], [50, 65], [10], []]
homer_scores and simpsons_scores[2] reference the same list object
(which Python manage for us somewhere in the memory)
Post by RaeNye
Post by Nir Soffer
homer_scores.append(11)
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]
Post by RaeNye
Post by Nir Soffer
del lisa_scores
lisa_scores
File "<stdin>", line 1, in ?
NameError: name 'lisa_scores' is not defined
That was evil!
Post by RaeNye
Post by Nir Soffer
simpsons_scores
[[90, 85, 80], [50, 65], [10, 11], []]
F**k! they are still there!? hmm, lisa_scores was not the list, its
only a name, the list is still there. This is exactly what Python told
us just now: "NameError: name 'lisa_scores' is not defined".
lisa fixes the situation
Post by RaeNye
Post by Nir Soffer
lisa_scores = simpsons_scores[0]
lisa_scores
[90, 85, 80]
Now [[90, 85, 80], [50, 65], [10, 11], []] is a lousy way to keep this
kind of data, because we have to remember the order of the family
members. This leads naturally to dicts - because we need it NOW to
write simpler and more readable code.
I hope it helps, It was fun to write :-)
Best Regards,
Nir Soffer
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
guy keren
2005-12-04 22:43:47 UTC
Permalink
Post by RaeNye
Post by Nir Soffer
Why use "thing"? simply talk about "list1"
Set the first item of list1 to the number 1
This is where you bluntly mislead the students.
"list1" is /nothing/ but the object it's currently binded to, and it's ultra
important that they understand this.
oh... now i need to explain the word "bind"? :)

i hate this word - it sounds too bombastic. it also does not come from
normal life - in normal life, you dont bind names - you just call your
bear "teddy". and binding is not exactly the same as "calling by name":

if i call my bear teddy, and then i go and tear its head, and its legs and
arms and stomach - is it still teddy? in python, if i name a list object
'teddy' and then i delete most of the list's items, it is still called
'a', regardless of any emotions i have towards this list.

please understand that "intuitive" is an illusion - any analogy that
you'll bring will have some exceptions, which you'll have to explain
eventually. which is why i'd rather explain things explicity, then count
on the intuition of the pupils. and since i cannot explain everything,
eventually i have to tell them "try it out and see how it works".
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
Amit Aronovitch
2005-12-04 16:15:37 UTC
Permalink
Post by guy keren
Post by Amit Aronovitch
Meta
====
In this essay I'll try to clearly state some of my ideas about variables in
python and how to teach the subject to students new to programming.
lets cut the long talks. in order for me to understand what you're trying
to do, i would like you to explain the following scenarios using the
Now, after I spent the long time writing this "long talks", at least
people can understand ME without endless Q&A's.
Now they can make themselves clear by saying just where their opinion
differs than mine. For people whose views are close to mine - this
allows expressing alot more with "short talks" :-)
Post by guy keren
Post by Amit Aronovitch
list1 = [2, 3]
list1[0] = 1
print list1
[1, 3]
Ahh lists...

The first thing I have to say here is that IMHO, any real problems here
(if at all) are related to the *list* concept, which is completely
seperate from the *variable* concept. When you say a=3 you get variable
which is not a list, and when you say a=[1,2]+[3] you get two nameless
lists (not tied to any variable).

Now the *list* concept, I have to admit, is abit more abstract. Maybe
5-years-old child one, rather than 2.5 year-old one (I'll probably know
better when my son grows up a bit ;-) ).

I think a good daily object to compare to is a physical list written on
a piece of paper with a pencil.
When you say list1[0] = 1, this means you go to the piece of paper,
erase the first item, and write 1 instead.

For example: suppose you have too such notes, "the blue note" and "the
red note"

the blue note says:
0) My dad's car
1) 7
2) Teddy the bear

the red note says:
0) The blue note
1) My dad's car
2) The blue note

Now, if I go and paint my car white, both blue_note[0].color (the color
of the first item in the blue note) and red_note[1].color will be white.
If i change blue_note[1] with 5, both (red_note[0])[1] and
(red_note[2])[1] will be 5.

The abstraction needed here is really the generalizing the "reference"
property of names to other things (you don't actually have to *say*
reference, but it might help) - you just have to understand that the
text strings on your note represent real objects the same way as names do.
(This is not really the hard part of the concept. Maybe the harder
thing is to understand that list[0] can be a label without there being
any real text line saying "My dad's car":
for example, the pupil might expect "list[0]" to print "'dads_car'"
instead of "repr(dads_car)" )
Post by guy keren
Post by Amit Aronovitch
a = 1; b = 2; c = 3
list1 = [a, b, c]
list2 = [b, c]
print list1
[1, 2, 3]
Post by Amit Aronovitch
print list2
[2, 3]
Post by Amit Aronovitch
list1 = [1, 2]
list2 = [3, 4]
mlist_a = [list1, list2]
print mlist_a
[[1, 2], [3, 4]]
Post by Amit Aronovitch
mlist_a[1] = list1
print mlist_a
[[1, 2], [1, 2]]
These all seem obvious to me if you use the physical note example. If
you think otherwise, please say exactly where you think the student
would expect any other result, and we can come up with a solution.
Amit Aronovitch
2005-12-04 18:12:37 UTC
Permalink
Rereading my essay, I think I begin to understand where the "mutable -
immutable" comments come from
(You see - it was even useful to ME ;-) )

Before I go on, just one petty remark (re: the quotes in the essay) -
mutability is a property of objects, not of names (it's actually a
categorization of types, and objects are typed), so you have to say
"mutable values", not "mutable variables".

To explain where the 'common concept' variables might cause unavoidable
Post by Amit Aronovitch
Note that usually they would not say all of that in the first lesson (as
this is
obviously too complex). Instead they would just develop this mental picture
gradually. They'd start with "named areas of memory", then at some point
they
have to explain stuff like "a=[];b=a;b.append(1);print a,b" and things start
getting complex real fast.
Now, I 'd used a *list* in my example[1], which is a mutable object.
Why's that?
Because in almost any program (unless your'e writing pretty delicate
things relying on reflection) you expect to see the exact same results
whether you use the same object or a copy of it - unless you actually go
and *change* the object. And you can only[2] change a *mutable* object.

If we stick to "examples should only use code that does useful things"
(one of the best tips I recently learned from you :-) ), you'll only be
able to see any difference between the two variable models if your
objects are mutable. List is the first multable type in this course, so
now your comments make more sense to me.

-------
[1] Obviously, using "is" or "id", I could have shown the same thing
with immutables:
"a=3;b=a;print a is b", but you might want do the whole course without
mentioning 'id' and 'is'.

[2] More exactly, your'e not *supposed* to change immutable objects. In
fact, only last week I've done just that - changed a python string -
just to verify I got my ctypes.LP_c_char_p objects pointing where they
should. Obviously, this is *NOT* the sort of thing one would want to
show in a course...
guy keren
2005-12-04 22:38:09 UTC
Permalink
Post by Amit Aronovitch
Rereading my essay, I think I begin to understand where the "mutable -
immutable" comments come from
(You see - it was even useful to ME ;-) )
if you simply let the link i sent you sink in - you'll see part of the
light.

i will still insist on using the name variables, because i want my pupils
to be able to quickly switch to new programming languages in the future,
and not have a fixation about "how things were in python, and why it
doesn't work in C". by not telling them there are other things, i will
only create confusion in the long-run.

eventually, they have to realize that what is important is not how you
call something, but rather what it does.
Post by Amit Aronovitch
If we stick to "examples should only use code that does useful things"
(one of the best tips I recently learned from you :-) ), you'll only be
able to see any difference between the two variable models if your
objects are mutable. List is the first multable type in this course, so
nowyour comments make more sense to me.
if you judge what i write without looking at the entire course, then
you'll miss the point. unlike my pupils, i expect you to see the big
picture all the time ;)

and by the way, i am going to teach about about changing lists -
programming is very limited if you don't change objects. i can show you my
checkers game, in which i take advantage of this feature (and which is
what led me to figure out this references issue in python, in the first
place).
--
guy

"For world domination - press 1,
or dial 0, and please hold, for the creator." -- nob o. dy
Noam Raphael
2005-12-05 21:17:17 UTC
Permalink
Amit Aronovitch
2005-12-05 21:46:07 UTC
Permalink
Post by guy keren
Post by Amit Aronovitch
Rereading my essay, I think I begin to understand where the "mutable -
immutable" comments come from
(You see - it was even useful to ME ;-) )
if you simply let the link i sent you sink in - you'll see part of the
light.
If you mean the Fredrik Lundh link, it sunk in the minute I saw it -
most of it explains in a simple and clear way the things I've been
explaining over and over to people while helping them fix bugs (endless
variations of the
examples in the wiki ref). That's why I was so excited when you said you
were gonna use it for lesson 3.

It does not say anything about mutability. Only says something like
"some objects you can change, some not". This is almost a null
statement. Only thing to learn from is thinking why he put this
statement there in the first place - most probably because a lot of
people coming from other languages confuse assigning names to objects
with changing their contents (hence my Eddie=Teddy example).
Post by guy keren
i will still insist on using the name variables, because i want my pupils
to be able to quickly switch to new programming languages in the future,
and not have a fixation about "how things were in python, and why it
doesn't work in C". by not telling them there are other things, i will
only create confusion in the long-run.
No problems there (I even said something like "exact choice of words
does not really matter" in my long blurb).

What I'm trying to say is that to me at least it seems much better to
explain python variables (i.e. names) from scratch (based on real-world
meaning of the word "name", which is really close to python names).
With that alone you can already write simple programs.

After that, you might choose to go on about computer's memory storing
numbers, representing objects, and using (named) reserved areas in
memory as variables. This should seem much less confusing after you had
already written a program or two.

As opposed, if you explain how variables work in other languages
(harder concept IMO - involves computer's memory and encoding objects as
numbers), then let them believe for a while it's like that in python,
then when you get to the point where it does not work like expected, do
some more abstract explanations to explain python names using the
"common variable" concept, well - I think this way you work harder, and
the end result is programmers more likely to make bugs such as those I
mention in my wiki ref.

Note that I'm not suggesting that you did it this way or the other - I
*don't know* what you actually said, nor what your exact plan for the
future is (I got clues both ways, and I imagine your way is most likely
some third option I can't see right now).

The important thing about all these arguments is not to convince you
one way or the other (though I might try anyway), but to better
understand how you think about that.
After all, if we want to write useful slides - they better match what's
being tought in the course.
Post by guy keren
eventually, they have to realize that what is important is not how you
call something, but rather what it does.
Post by Amit Aronovitch
If we stick to "examples should only use code that does useful things"
(one of the best tips I recently learned from you :-) ), you'll only be
able to see any difference between the two variable models if your
objects are mutable. List is the first multable type in this course, so
nowyour comments make more sense to me.
if you judge what i write without looking at the entire course, then
you'll miss the point. unlike my pupils, i expect you to see the big
picture all the time ;)
and by the way, i am going to teach about about changing lists -
programming is very limited if you don't change objects. i can show you my
checkers game, in which i take advantage of this feature (and which is
what led me to figure out this references issue in python, in the first
place).
I never imagined you'd want to avoid changing stuff. Lists are intended
to be changed (otherwise tuples would be enough)

It's Just that the word "immutable" automaticly makes me think about
dict keys and hash functions (the only place where it's important that
the object *can't* change).
Had you said something like "changing the objects to demonstrate
references", it might not have seemed comlpletely incomprehensible to me.
It's the actual changing of the object that counts (not whether or not
the language allows you to do so), and it only counts because it makes
the difference demonstratable (which is, of course, very important).

Misunderstandings are all about choice of words...

Amit Aronovitch
2005-12-04 18:52:58 UTC
Permalink
Post by Amit Aronovitch
* Variables are named areas of memory storing data of some type.
* Pointers are variables storing memory addresses of other variables.
* Python works by reference. This means that variables are actually
implemented as pointers (i.e. store memory addresses), but the language
does implicit dereference whenever they appear in expressions (i.e.
operations other than assignment work on the area pointed to by the
pointer
rather than the pointer itself).
Just emphasizing the importance of the phrase "other than assignment" above:

Fortran, for example, uses "by reference" arguments passing, but it's
variable concept is much the same - the assignment operator works on the
*value* rather than the pointer (i.e. doing a=b you get a *copy* of b).

In other words - "python vars" vs "common vars" is not the same as "by
reference" vs "by value".
Loading...