[Edu-sig] what is a "variable" in Python?

Mark Engelberg mark.engelberg at gmail.com
Tue Feb 16 04:13:09 EST 2016


First, add me to the chorus of people saying that using the term "variable"
to categorize mutable objects versus immutable objects is counter to the
way every programmer uses and understands the term "variable" to mean a*
name *that can take on multiple values over the lifetime of a program.
Sounds like you've already been convinced about this by the others, so I
won't belabor that point here.

So let's move on to the topic of "containers" versus "labels" as a metaphor
for variables.  I have used both, and I think both work equally well with
students (but we can do better, more on that in a moment).  Your main
argument against containers is that it goes against real-world intuition to
have one value in two containers.  This is easy enough to rectify.  Each
container is designed to hold a piece of paper with enough space to write
64 0's and 1's.  Putting something in a container simply means we write the
64 0's and 1's that describe where to find the object in the computer's
memory -- an address -- and put that piece of paper in the container.  No
student has a problem with the idea of two containers, each containing
their own piece of paper that happens to have the same number written on
it.  Arguably, the "containers of addresses" model is more precise than the
label model.

But we can do better than both the container and label model.

The clearest teaching model: A variable is simply an entry in a dictionary.

First, we need to talk about what it means for the Python interpreter to
interpret or "evaluate" an expression.
When I type x+y at the interpreter, what does that mean?  How is that
evaluated?  Well, it's completely meaningless unless we know what the value
of x and y are.  Python keeps around a dictionary/table that stores
associations between names and values.

When I say x=2, all this means is that I'm adding an entry (or modifying an
existing entry) in the main (global) dictionary that says x is now
associated with 2.
When I evaluate an expression like x+y, Python looks up the values for x
and y in its dictionary.

Right-hand sides of assignments are always evaluated first before an entry
is put in the dictionary.  So z=x first evaluates x, by looking it up
(right now, it's 2) and then adding an entry in the dictionary between z
and 2.  (By using this more precise mental model, students now won't get
tripped up by things like x=2, z=x, x=3 and thinking that somehow z has
changed).

Every function keeps around its own dictionary of name/value associations.
When evaluating expressions inside a function, Python first tries to look
up the name in the function's dictionary, and if not found there, works its
way outward to the global dictionary (for beginners, there aren't likely to
be more than two levels, so you can simplify this discussion a bit for
beginners by talking about only two levels until you get to nested
functions).  When Python evaluates an assignment inside a function, it
evaluates the right-hand-side using the rule just given, and then creates a
new entry in the function's dictionary.  (By using the more precise mental
model, we've just explained some of the most complex intricacies of lexical
scoping and how it behaves in Python, including a lot of surprising gotchas
where people think they are assigning a global variable, but are actually
just creating and assigning a new local variable.)

I'm not opposed to giving simplified mental models to beginners and then
later saying, "I lied before.  It's really more complicated than that."
But only if it's necessary.  In this case, it's not.  The dictionary model
is more accurate, and no more difficult for students to understand.  It's
sort of like the label model, but more detailed because it tells us where
these connections from labels to values actually live.  This allows
students to use their intuition they've developed from working with
Python's dictionary data structure in order to understand how name/value
associations are created, modified, and accessed.  It provides far more
context for understanding scoping.  So I advocate for using this model from
the start.

The difference between the dictionary model and the label model is subtle,
but it does require you to use different visual images to explain what is
going on.  Instead of showing objects put into boxes, or showing post-its
attached to objects, when you step through a program on your whiteboard for
the students, start off by drawing a big blank "piece of paper" off to the
side labeled "dictionary".  As you step through the program, write in new
name/value entries on the dictionary.  When you reassign a variable, find
that name in the dictionary and erase the value that's there, and write in
the new value.  When you enter a function, draw another "piece of paper"
near the function to contain its name/value associations.  Give them this
clearer visual imagery as you step through the program -- you'll be glad
you did.

When you want to get into mutability/immutability, instead of writing the
actual value next to the name on the dictionary page, write the value at
some random location on the board (you can draw a cloud to represent the
computer's memory, and write the value in that area), and then the
dictionary just contains the name and next to it an arrow to the value out
in the memory (or use the address metaphor I described above if you
prefer).  This helps understand how two names can connect to the same
object.

Hope this helps,

Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20160216/e556cf39/attachment.html>


More information about the Edu-sig mailing list