Doors Which Should Remain Closed

A couple of years ago my son went on a school trip to the offices of The Guardian newspaper to learn about journalism and web development. It was strange for a few reasons, the first of which is that the trip was even organised in the first place since journalists for The Guardian are particularly energised by the idea of shutting down my son’s school. On his return, I asked him the entry level parenting question “What did you learn?” hoping that he would say something amusing like “Oh, they opened a door and showed us the room where they write the articles demanding the closure of my school.”

Less amusingly, instead he was shown some Javascript code and introduced to The For Loop and The Post-Increment Operator. The For Loop is a fundamental part of any computer program and arguably a good starting point for beginners. But it’s also a very strange thing.

1
2
3
4
let numSelected = 0;
for (let i = 0; i < items.length; i++) {
numSelected += item[i].isSelected() ? 1 : 0;
}

Consider the above for statement. The truth is, The For Loop is not like any other construct in Javascript. It looks like a branching construct called ‘for’, but within the parentheses live sections of code, one part of which is evaluated once and has implications for the block of code within the for loop and the other parts are code which are not immediately evaluated but somehow frozen and evaluated later. There is nothing else in Javascript like this. Anyone who comes away from learning about the for loop thinking that when you see parentheses you can insert statements separated by semi-colons is going to be sorely disappointed.

If anything the for loop is like a macro statement, but the everyday commonness and usefulness of The For Loop blinds us programmers to its nature. You can see the majority view of coders clearly in the responses to this Quora question entitled ‘Why is the foor loop in C so weird’ where almost every answer flatly denies that it is weird (e.g. “Seriously?”).

Within the for loop shown above there is the other part of my boy’s learnings, the post-increment operator. This is also quite weird. The post-increment operator changes the value in the variable and yet returns the value the variable had before it was incremented. Well, that’s the simplest way of thinking about it. You could also think that the post-increment operator returns the value and then in some other out-of-this-world time period increments it, hopefully, before anything else happens. It not relevant to my point which one it is, in either case there’s some strange behaviour going on. To hammer the point home, this is not like the other operators which return the result of their operation – an operator which doesn’t return the result of its operation is an odd creature.

From a pedagogical perspective, it’s probably better to start with normal things rather than strange ones so that the student is able to map what they have already learned to new concepts as they come across them. Furthermore, not only would I not start from here, I’m not even sure I would go there either. The post-increment operator is just asking for trouble since its strangeness is behavioural unlike the for loop where the strangeness is syntatic. You only use the post-increment operator if you are using a looping construct where you want to both test a value and increment it in the same statement, but you never need to do this, it’s only a terse way of implementing a loop and perfectly good, if less terse, alternatives exist.

A budding programmer will inevitably use the for loop a lot but the problem I have is that it encourages you to write code in larger units that mushes iteration in with operations on items. Everyone agrees that code should be composed of small units which do few things rather than many, and everyone agrees that “don’t repeat yourself” (DRY) is a fundamental principle of programming. But the for loop encourages you to go against these principles and entwine iterating and operating such that your code units do more, are not simple and have essentially identical for loops duplicated throughout the codebase. The map function encourages you to write simpler code that concerns itself with operations only rather than iteration and operation. Additionally, you can trust map to iterate correctly therefore you can test your operations individually without having to test that you are iterating correctly too. That means your tests are simpler too.

That’s why I said to my son, “You probably want to avoid that stuff.” and then, “they didn’t show you that room did they?”.