The interpreted language Python is a lot of fun. It’s great
for quick and dirty lash-ups, and has list comprehensions whilst being easier
to use that Haskell. There are many great reasons why you would never deploy it
in a production environment, but that’s not what this article is about.
In the UK, the government decided that schoolchildren needed
to learn to code; and Python was picked as the language of choice.
Superficially it looks okay; a block structured BASIC and
relatively easy to learn. However, the closer I look, the worse it gets. We
would be far better off with Dartmouth BASIC.
To fundamentally understand programming, you need to fundamental
understand how computers work. The von Neumann architecture at the very least.
Sure, you can teach CPU operation separately, but if it’s detached from your
understanding of software it won’t make much sense.
I could argue that students should learn machine code (or
assembler), but these days it’s only necessary to understand the principle, and
a high level language like BASIC isn’t that dissimilar.
If you’re unfamiliar with BASIC, programs are made up of
numbered lines, executed in order unless a GOTO is encountered. It also incorporates
GOSUB/RETURN (equivalent to JSR/RTS), numeric and string variables, arrays, I/O
and very little else. Just the basic building blocks (no pun intended).
Because of this it’s very quick to learn – about a dozen
keywords, and familiar infix expression evaluation, and straightforward IF..THEN
comparisons. There are also a few mathematical and functions, but everything
else must be implemented by hand.
And these limitations are important. How is a student going
to learn how to sort an array if a language has a built-in list processing
library that does it all for you?
But that’s the case for using BASIC. Python appears at first
glance to be a modernised BASIC, although its block structured instead of
having numbered lines. That’s a disadvantage for understanding how a program is
stored in sequential memory locations, but then structured languages are easier
But from there on, it gets worse.
Data types are fundamental to computing. Everything is digitised
and represented as an appropriate series of bits. You really need to understand
this. However, for simplicity, everything in python is treated as an object,
and as a result the underlying representation is completely hidden. Even the
concept of a type is lost, variables are self-declaring and morph to whatever
type is needed to store what’s assigned to them.
Okay, you can do some cool stuff with objects. But you won’t
learn about data representation if that’s all you’ve got, and this is about
teaching, right? And worse, when you move on to a language for grown-ups, you’ll
be in for a culture shock.
A teaching language must have data types, preferably hard.
The next fundamental concept is data arrays; adding an index
to a base to select an element. Python doesn’t have arrays. It does have some
great built in container classes (aka Collections): Lists, Tuples, Sets and
Dictionaries. They’re very flexible, with a rich syntax, and can be used to
solve most problems. Python even implements list comprehensions. But there’s no
Having no arrays means you have to learn about the specific
characteristics of all the collections, rather than simple indexing. It also
means you won’t really learn simple indexing. Are we learning Python, or
fundamental programming principles?
Unlike BASIC, Python is block structured. Highly structured.
This isn’t a bad thing; structuring makes programs a lot easier to read even if
it’s less representative of the underlying architecture. That said, I’ve found
that teaching an unstructured language is the best way to get students to
appreciate structuring when it’s added later.
Unfortunately, Python’s structuring syntax is horrible. It dispenses with BEGIN and END, relying on the level of indent. Python aficionados will tell you this forces programmers to indent blocks. As a teacher, I can force pupils to indent blocks many other ways. The down-side is that a space becomes significant, which is ridiculous when you can’t see whether it’s there or not. If you insert a blank line for readability, you’d better make sure it actually contains the right number of spaces to keep it in the right block.
WHILE loops are support, as are FOR iteration, with BREAK
and CONTINUE. But that’s about it. There’s no DO…WHILE, SWITCH or GOTO.
You can always work around these omissions:
You can also fake up a switch statement using IF…ELSEIF…ELSEIF…ELSE.
Really? Apart from this being ugly and hard to read, students are going to find
a full range of control statements in any other structured language they move
In case you’re still simmering about citing GOTO; yes it is
important. That’s what CPUs do. Occasionally you’ll need it, or at least see
it. And therefore a teaching language must support it if you’re going to teach
And finally, we come on to the big one: Object Orientation.
Students will need to learn about this, eventually. And Python supports it, so
you can follow on without changing language, right? Wrong!
Initially I assumed Python supported classes similar to C++,
but obviously didn’t go the whole way. Having very little need to teach
advanced Python, I only recently discovered what a mistake this was. Yes, there
is a Python “class”, with inheritance. Multiple inheritance, in fact. Unfortunately
Python’s idea of a class is very superficial.
The first complete confusion you’ll encounter involves class
attributes. As variables are auto-creating, there is no way of listing
attributes at the start of the class. You can in the constructor, but it’s
messy. If you do declare any variables outside a method it silently turns them
into global variables in the class’s namespace. If you want a data structure,
using a class without methods can be done, but is messy.
Secondly, it turns out that every member of a class is public. You can’t teach the very important concepts of data hiding; how to can change the way a class works but keep the interface the same by using accessors. There’s a convention, enforced in later versions, that means prefixing a class member with one or more underscores makes it protected or private, but it’s confusing. And sooner or later you discover it’s not even true, as many language limitations are overcome by using type introspection and this rides a coach and horses through any idea of private data.
And talking of interfaces, what about pure virtual
functions? Nope. Well there is a way of doing it using an external module.
Several, in fact. They’re messy, involving an abstract base class. And, in my
opinion, they’re pointless; which is leading to the root cause why Python is a
bad teaching language.
All Round Disaster
Object oriented languages really need to be compiled, or at
least parsed and checked. Python is interpreted, and in such a way as it can’t
possibly be compiled or sanity checked before running. Take a look at the
eval() function and you’ll see why.
Everything is resolved at run-time, and if there’s a problem the program crashes out at that point. Run-time resolution is a lot of fun, but it contradicts object orientation principles. Things like pure virtual functions need to be checked at compile time, and generate an error if they’re not implemented in a derived class. That’s their whole point.
Underneath, Python is using objects that are designed for
dynamic use and abuse. Anything goes. Self-modifying code. Anything. Order and discipline
are not required.
So we’re teaching the next generation to program using a
language with a wide and redundant syntax and grammar, incomplete in terms of
structure, inadequate in terms of object orientation, has opaque data representation
and typing; and is ultimately designed for anarchic development.
Unfortunately most Computer Science teachers are not software engineers, and Python is relatively simple for them to get started with when teaching. The problem is that they never graduate, and when you end up dealing with important concepts such as object orientation, the kludges needed to approximate such constructs in Python are a major distraction from the underlying concepts you’re trying to teach.