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.