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.

14/10:
>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?

4/11:
>>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.

6/11:
>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.

20/11:
>   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?

2/12:
>>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.

לענות