Opposing Forces
I’ve been thinking a bit about the teaching of programming. Like any technically intense subject, there’s a necessary balance between two (somewhat) opposing forces. These are:
- Dumping1 as much information as possible on the students, so that they can successfully navigate the labyrinthe that is whatever topic you’re trying to teach them.
- Actually effectively teaching them anything.
The important point here is that, while you can get a bunch of students to memorize a bunch code snippets, the difference between call()
and apply()
and bind()
, or all of the standard methods on the String
prototype2, this does NOT constitute teaching. In this post, I’m gonna examine the ways in which we can first ineffectively and then (hopefully!) effectively hit both marks.
How Not To Do It
A.K.A., the Look At What I Can Do method
There’s an old, famous adage in teaching: Show, don’t tell. Basically, teachers shouldn’t just tell students that an idea is true, but rather demonstrate it. Obviously, there are limits to this. For example, all of euclidean geometry is based off of the unprovable assumption that, simply put, a point is a point, a line is a line, and a plane is a plane3.
Unfortunately, a lot of ineffective teaching stems from the assumption that because you tell students something, they’ll learn it. I could go into a completely separate tangent about Howard Gardener’s multiple intelligences, and how verbal learning is only one of at least seven separate styles, but suffice it to say that this is almost never an effective pedagogical method.
What’s worse, this lack of absorption is often compounded by severe information overload. Here’s an example:
- You’re teaching JavaScript, and you have a class of completely beginner programmers. They know how2computer, but they’ve never touched code in their lives.
- You show them the following script:
var myName = ‘Dave’;
myName = prompt(‘Enter a name please.’);
function sayHi(n){
alert(‘Hello ‘+n+’!’);
}
sayHi(myName);
Fig 1: A “simple” code example
Simple, right? It just asks for their name and then says hello! Great way to introduce a simple bit of JavaScript, right?
Wrong! Remember, you’re (most likely) looking at this from the perspective of a relatively seasoned programmer. You know what we mean when we have a word followed by parentheses (i.e., myFunction(thing)
). You know what variables are. So you look at this example and automatically know what it does. But imagine someone who’s never seen a programming function, or worse, has yet to go through high-school algebra (i.e., does not know what a variable is). For that person, the concept of changing variables4 may be still foreign to them.
This is an example (albeit a comparatively simple one) of a case of telling and not showing. In this case, our hypothetical teacher (you) assumes that because you already have the knowledge, it’ll be easy for your students to learn. The teacher fails to make the cognitive prediction between amount of knowledge that the students need to gain before they’re competent and the cognitive “leaps” that they can effectively take to get to that knowledge
Worse still, the student may not realized that they haven’t learned the material effectively until too late (i.e., the exam, or when they need to use this knowledge in a real-world scenario). This stems from the copy-and-paste programming education that this “tell” style of teaching lends itself to. Imagine that you’re a student in the above class. You’re told to copy and paste the above code, but you can (for now) change whatever’s between the quotes. You write:
var myName = ‘Bob’;
myName = prompt(‘Who are you?!’);
function sayHi(n){
alert(‘Greetings, ‘+n+’!’);
}
sayHi(myName);
Fig 2: The student writes some code
So you run your code, and hey, it works! It says something different now, so that must mean you know what you’re doing. Right?
Well, no. It means you’ve copied some code directly. While this is fine later on (hello, Stack Overflow), this doesn’t teach you anything except how to type. Your teacher introduced at least 7 different concepts here5. Because these are relatively fundamental concepts, your teacher assumed that they’d be basal enough that anyone would either know them, or immediately “get” them.
Instead, we need to ask what the most fundamental pieces of these scripts are, and how we can break them down into (still functioning!) pieces that teach only a few concepts at a time.
The Pillars of Programming
A.K.A., What’s Actually Important
So what are these fundamental pieces? Well, to answer that, perhaps we’d better start by asking what’s common to all (or at least, most) languages6. This’ll help us see what particular pieces we may wrongly assume everyone already knows. Here’s my list (feel free to skip this section if you want):
Variables: var myVar = 'chocolate'
In order to store information, your program needs little boxes in which to store that stuff. Just like you might label a box in your closet “shoes”, or a drawer “silverware”, we might label a ‘box’ in our code as myVar
. We could then store in this box your favorite flavor of ice cream. In some languages, different variables can store different kinds of information. Your cardboard shoebox can store shoes, but you’d probably not wanna store last night’s chicken stew in there.
Arrays/Lists: var simpsons = ['Lisa','Bart','Maggie','Marge','Homer']
Remember how we said different variables can store different stuff? Well, some variables are designed to hold multiple bits of information. In the example above, the variable simpsons
stores all of the (human) members of the Simpsons’ family. Just a useful way of organizing information!
Conditionals: if(condition) then actionIfTrue else actionIfFalse
Programs are famous for making complex decisions. It was, generally, why the first programs are written. Conditionals allow a program to interpret different input and change depending on what that input says. For example, let’s say you write code for a robot to sort your house out. It inspects each container in your house and then puts the appropriate item in there. You might have something like the following
if (box_for_shoes==true) then
Put_Shoes_In
else if (box_for_tupperware==true) then
Put_Stew_In
else
Yell “I don’t know what to do!”
end
Fig 3: Example of a conditional7
Your robot inspects the box, and first asks “Is it a shoebox?”. If yes, it sticks shoes in there. If no, it then asks if the container is tupperware. If so, it sticks stew in there. Finally, if neither of these is true, it screams at you in frustration.
Loops: while (thing is true) then do something
Imagine your house-sorting robot needs to sort 1000 boxes (you really need to do something about your boxes, dude). You could write the above conditional 1000 times. Or, you could not drive yourself completely insane, and use a loop! Note that, for the example below, we’re pretending that “sort_a_box
“ just tells the robot to, well, sort that box.
var num_boxes = 1000
while (num_boxes>0) do
sort_a_box
num_boxes = num_boxes - 1
end
Fig 4: Example of a
while()
loop
So we start out with 1000 boxes. Then we have a loop, where each time it asks “Is the number of boxes greater than zero?” If so, it continues. Otherwise, it stops. Finally, we subtract 1 from the number of boxes, so that our robot essentially ticks one box off as being ‘done’ each time. Note that there’s no “false” condition for this loop: there’s no while (thing is true) then do_something otherwise do_other_thing
Another incredibly useful type of loop is the for
loop. This loop basically runs a set number of times. So if you wanted to say “Hi!” 10 times, you could do:
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
say “Hi!”
Fig 5: Code repetition
Pretty repetitive, right? Alternatively, you could do the following:
var i = 0;
for i,i<10,i+=1 do
say “Hi!”
end
Fig 6: for()
Loop
So much more compact! This loop tells us to start by making a variable named i
, and setting it to zero. We then start our loop. During each iteration of the loop, we look at i
and ask whether it’s still less than 10. If it is, we increment i
by one and do another iteration. Otherwise, we stop.
Functions/Methods: function myFunc(name) do say "Hello, "+name endFunc
Loops are pretty great at making our code more efficient, but what if we have bigger blocks of code that we wanna pass around? Or, worse, what if we don’t know the order in which we want our code to run? This is where functions (also known as methods in some areas) come in. Functions allow us to write blocks of reusable code that we can pass around for different areas of the code to “borrow”.
Let’s stick our conditional example from above in a function
function shoe_or_stew(box_for_shoes,box_for_tupperware) do
if (box_for_shoes==true) then
Put_Shoes_In
else if (box_for_tupperware==true) then
Put_Stew_In
else
Yell “I don’t know what to do!”
end
Fig 7: My First Function
The bits between the parentheses are called arguments. They basically allow us to pass in information for our function for each ‘run’ of that function. So each time our robot gets a new box, it runs this function. If the value passed in for box_for_shoes
is true, then it’s a shoebox. If the value for box_for_tupperware
is true, it’s a tupperware container. And if neither is true, yell in frustration.
Blocks: do some_stuff end
You may have noticed in the past few examples the words do
and end
. These sit on the ends of sometjing in programming called a block. Wikipedia defines a “code block [as] a section of code which is grouped together” (Wikipedia:Block Programming). We can then do things with those blocks, like use them as the result of a conditional, or the contents of a function.
In some languages, the blocks are denoted by curly brackets ({
and }
).
1 I deliberately use the term “dumping” here, for reasons I’ll explain later.
2 Can ya tell what language I’m using here? I’m totally not a JavaScript fanboy or anything. Nope.
3 This is actually not exactly what the postulate says, but it’s close enough.
4 Variable variables?
5 Variables, functions, strings, function arguments, the alert()
method, programming blocks ({...}
), and calling functions.
6 Of course I mean programming languages here, but interestingly enough, there are common features to spoken/human languages as well that basically allow us to learn other languages. These include things like verbs, nouns, descriptive words, and some sort of system for distinguishing what words play which “role” (i.e., subject vs. object).
7 We would, of course, at some point also want to mention why we use ==
vs =
.