Guidelines for Teaching Programming

Decorative image showing the text "Guidelines for Teaching Programming" as the heading of an academic paper

How to teach programming is a hot topic again. 23 years ago (!) I wrote a paper titled “Guidelines for Teaching Object Orientation with Java” that provided some guidelines (eight, to be exact).

And although, as the title suggests, this was specific to OO and Java, I was wondering how many of these would stand up today. I was surprised to see that almost all of it – I think – is still relevant, and almost all of it we still cannot take for granted.

So I will, over the next few days, revisit the guidelines here, one at a time, and add my comments outlining how much of each I think still applies in “modern times”.

Watch this space over the next week or two for the discussion.

A brief history of programming languages

While I was thinking about the history of programming languages recently, I remembered slides I once made, showing a (simplified) family/influence/history diagram of languages.

Shared he in case it’s useful to anyone.

(It was made many years ago, so not up to date after 2010 – sorry. And I fully expect your comments correcting my interpretations…)

A graph showing several programming languages from 1957 to 2012 and their relationships

Some programming languages and their relationships (up to 2010)

The same graph as above, but with languages highlighted that use C-style syntax

Languages with C-style syntax

The same graph as above, but with functional languages highlighted

Functional languages (some languages intentionally on the border…)

The same graph as above, but with object-oriented languages highlighted

Object-oriented languages (some languages intentionally on the border)

Here is a PDF file with the same diagrams.

In Honour of Niklaus Wirth

Niklaus Wirth died in Zürich on 1st January 2024. He was one of the great pioneers of programming language design, and specifically design of languages for education.

His languages were a huge influence on me, and on my thinking. Pascal was one of the first languages I learned, and Modula-2 and Oberon also opened worlds to me when I understood what lay behind their design.

The Informatics in Education journal has just published a special edition to honour Wirth’s tremendous contribution to our community. I contributed an article to this edition, titled Principles of Educational Programming Language Design.

I invite you to read it; it might be of interest to you if you are interested in programming language history, in the design of programming languages or in programming education.

The entire special edition is worth a look. It contains many other interesting contributions.


In 2002, I had the honour to introduce Wirth’s keynote address at the ITiCSE conference in Aarhus, and to have dinner with him. One of my treasured memories.

Image of Niklaus Wirth and Michael Kölling, sitting at a table at dinner.

Niklaus Wirth and I (in much younger years), at the conference dinner at ITiCSE 2002, in Aarhus

Sitting at a dinner table, chatting, are (from left to right): Michael Kölling, Niklaus Wirth, Michael E Caspersen, David Gries

At the ITiCSE 2002 conference dinner (left to right): Michael Kölling, Niklaus Wirth, Michael E Caspersen, David Gries

Designing a programming language: Don’t Be Clever

One lesson of programming language design? Don’t try to be too clever!

Here is an example from JavaScript​:

When you compare

0 == ‘0’

the system tries to be clever: “Comparing a number and a string? You probably meant to see whether the string contains the character ‘0’, so let’s just say ‘yes’!”, it thinks. So the result is true.

When you compare

0 == ”

it tries to be even cleverer: “Ahh, perhaps you meant to check whether the length of the string is zero! Let’s just help the user here and not require them to call a ‘length’ function. So tedious. It’s true!”

But of course

‘0’ == ”

“Comparing two strings – got it. Are they the same? No! Returning false.”

The result of all this: The fundamental property of transitivity of equality is broken in JavaScript!

a == b and b == c, therefore a == c ?

Not in JavaScript, it isn’t! How can anyone voluntarily program in a language like this?!

The lessons for me? Give me static typing any day. And don’t try to be clever when designing a language. Spelling things out is a good thing, not a bad thing.

The terrible state of MCQs

In academia – as in many other contexts – Multiple Choice Questions (MCQs) are a fact of life. We have many situations in which we need to assess a large cohort of learners, and MCQs make this easier.

Here, I don’t want to debate the value of MCQs as an examination technique in general, but talk about how they are written. If we accept that they are part of our work, let’s at least make them not terrible.

There are three very common ways in which MCQs can be obviously bad. I see them all the time.

They are:

  1. The question only examines surface knowledge
  2. The distractors are random
  3. The off-by-one way of writing distractors

Let’s look at each briefly.

The question only examines surface knowledge

This is quite an easy and obvious shortcoming to recognise: Often, MCQs just ask questions about terminology. They do not touch on concepts or deeper understanding. This is a very common trap to fall into for people who are not used to writing MCQs. Writing MCQs that test understanding is harder, and it’s easy to slip into the trap of just testing surface issues.

We have probably all seen it.

When you write your questions, examine each question critically in this light. Strive for meaningful questions.

The distractors are random

Another very common gripe of mine is that the distractors (the incorrect options in MCQs) are chosen at random. Let’s consider an example. Assume we have this question:

Question 54:

What is the output of the following segment of code?

        int sum = 0;   
        for (int i=0; i<=5; i+=2) {
            sum = sum + i;
        }
        System.out.println(sum);

If you speak Java, then you can work out that the answer is 6. So we use 6 as one of the possible options, and add a few random distractors:

Answer:

(A) 1
(B) 896
(C) 6
(D) -4
(E) 5

In this case, if students have a common misconception, they may arrive at an answer that is not on the list. For example, a student who does not understand that this definition makes the loop increment by 2 might assume that the answer is 15. But 15 is not on the list. So the student is implicitly told that they are wrong, and they can discard unlikely options (“Negative? – No.” “More then 800? – No.”) and make a random guess between a few remaining options.

This question is even worse in a way: Another common mistake is not being able to correctly distinguish between <= and < in the loop condition, and getting the answer wrong because of this. The way the question is written, however, it is not even possible to expose this misconception, because both variants happen to result in the same output!

A badly written question.

The off-by-one way of writing distractors

The other very common pattern I see all the time has an example in this question.

Question 31:

 Which of the following code segment would execute the stored procedure “getPassword()” located in a database server?

  1. CallableStatement cs = con.prepareCall("{call.getPassword()}");
    cs.executeQuery();
  2. CallabledStatement callable = con.prepareCall("{call getPassword()}");
    callable.executeUpdate();
  3. CallableStatement cab = con.prepareCall("{call getPassword()}");
    cab.executeQuery();
  4. Callablestatement cstate = con.prepareCall("{call getpassword()}");
    cstate.executeQuery();

The way questions like this are written is usually this: The question setter writes the correct response, and then creates three distractors by introducing one error in each.

It is trivial to reverse-engineer the correct answer from this. To do this, we spot the differences, and for each differences discard the odd one out. For example:

  • One difference is that “{call getpassword()}” is written with a dot in the middle once, but without the dot three times. So the dot is the odd one out, we discard Answer 1.
  • Another difference: CallableStatement is written with w capital S three times, with lowercase s once. So we discard answer 4.
  • Last one: The second line calls executeQuery() three times, and executeUpdate() once. Answer 2 is out.

And voilà – there is our answer: 3. We can do this without any knowledge or understanding of the subject matter. Keep your eyes open for this pattern in MCQ tests. It is astonishing how often you will see this question pattern.

A better example

Here is an example of something you could do:

Question 8:

HashMap<Integer, String> myMap = new HashMap<>();

myMap.put(2, "Tiger");
myMap.put(4, "Lion");
myMap.put(13, "Lion");
myMap.put(2, "Elephant");
myMap.put(3, "Chicken");

System.out.println(myMap.get(2));

When you try to compile and run this code, what will happen?

    1. The code has an error, because the value “Lion” is used twice in the HashMap.
    2. The code has an error, because the key 2 is used twice in the HashMap.
    3. The code will run and print “Tiger”.
    4. The code will run and print “Lion”.
    5. The code will run and print “Elephant”.

 In this case, the question tests an understanding of how maps work.

  • Option 1 tests the possible misconception that values cannot appear twice in a map.
  • Keys, on the other hand, are unique in a map. Option 2 tests the misconception that they cannot be replaced by a new entry.
  • Option 3 tests the misconception that the first entry for a given key persists.
  • Option 4 tests the misconception that the get(n)-parameter is an index, mirroring list-behaviour (referring to either the second or third element entered, depending whether the list is zero-based or one-based).
  • And Option 5 is correct.

This is by far not all that there is to say about MCQ writing. But it’s a start. It is the absolute minimum you should consider if ever you find yourself in the position to write and MCQ test.

Announcement: Strype – a frame-based Python system

Strype logoLast week, we have officially released Strype 1.0, a new Python editor and runtime system running entirely in a web browser. After being in development and available for preview and testing for some time, the system is now fully supported for use in classrooms or for individuals wishing to learn Python programming.

Strype’s most unique feature is its frame-based editor, a novel code entry and manipulation technique which makes writing of code quicker, easier and less error prone. In a manner similar to block-based systems, statements are entered and manipulated as single entities, and are laid out on screen automatically. Many syntax errors are avoided, indentation errors are not possible.

Sample of Strype code

While frame-based editing profits from some of the same advantages as block-based programming, it does not, however, suffers the same restrictions: programs in Strype have to full power of the Python language, purely keyboard-based efficient editing is supported, and programs retain the readability, navigability and maintainability of standard Python systems.

Strype is available free of charge, with no installation needed.

Links:

Strype webpage

The Strype editor

The Strype editor for micro:bit

Strype user community

Strype was developed by the Programming Education Tools Group at King’s College London. Team members: Pierre Weill-Tessier, Neil Brown, Michael Kölling

The New Joy of Code – 01: Introduction

Finally it is here: The first of the New Joy of Code programming series.

In this series of videos I will show you how to program in Greenfoot and Stride. Later in the series, we will also get to programming in Java. But ultimately, what you will learn are the principles of object-oriented programming, which you should then be able to apply to any language.

This first episode shows you what Greenfoot is, and what Stride looks like.

Download Greenfoot here.

Check back soon for more episodes.

 

The New Joy of Code – Coming Soon!

The most popular pages on this blog are the episodes of the ‘Joy Of Code’ video series, which teaches programming with Greenfoot. This video series, however, is somewhat outdated by now. So I have decided to update it and start again.

So, coming soon: The New Joy of Code. It will be similar to the old one, a series of short videos that can be used for self study, or in a classroom, but there will be differences: First, I will, of course, use a recent version of Greenfoot (Version 3.1.0 at the moment), but more importantly: I will use our new language Stride for the tutorial. We will later also transition into Java, but Stride is such a great language for beginning to program, that I really want to start with that.

With the videos – you’ll see!

Full paper on Frame-Based Editing out now

We (that is: Neil, Amjad and I) have worked on Stride and its frame-based editor for about four years now, and there is a lot of work in it.

First, Stride was designed and released as part of Greenfoot, and we wrote a few smaller papers about specific aspects of use cases around Stride. Then, more recently, we also incorporated Stride into BlueJ, making the new frame-based editor available to a much larger audience.

Frame editorIn parallel, we have worked on a comprehensive paper, describing the design ideas and rationale behind many of the detailed aspects. It also describes related work and background (which you might like to read in its own right if you are interested in the history of block-based systems or structure editing), and a few small user studies.

I’m glad it is out now; you can read it here:

Kölling, Brown & Altadmri: Frame-Based Editing

It has been published in a special edition of the Journal of Visual Languages and Sentient Systems (focussed on blocks programming). The rest of the special issue is very much worth reading as well – you can find it here.

I would like to thank all our reviewers who contributed many useful comments and suggestions, especially Jens Mönig and John Maloney, and the special editions editor Franklyn Turbak.