Can We Escape the Forever Loop?

If you’ve used Scratch or a similar program to teach coding, it’s likely you’ve helped a student who asked why code like this isn’t working:

When green flag clicked - if(space key pressed) - Move(10)

The student is pressing the space key, but their sprite isn’t moving. They don’t understand why.

“Well,” you say, “that’s easy. What’s happening is the code’s only running once, and it happens instantaneously, so if you’re not already holding down space when the program starts, it sees that the key isn’t down, moves on, and ends the program. All you need to do is wrap it in a forev-”

And I’m going to stop you right there, before you doom the kid to a loop he probably won’t escape for years. Let’s go back in time. It’s likely you at some point learned to code using some kind of a console app, maybe Python or if you are as old as me maybe BASIC. In any case, you probably have written a HelloWorld2 program that went something like this:

name = input("Hi, what's your name?")
print("Hello " + name + "!")

Now let me ask you this. Why do you not need to do something like this?

while(name == "")
    name = input("Hi, what's your name?")
print("Hello nice to meet you " + name + "!")

In other words, how does the compiler know to just sit there and wait for you to enter your name before just moving on and running the program and printing “Hello  !”

If your answer is, “Well, that’s just how console apps work!” then I am a bit disappointed but I’ll give you another chance. Why do console apps work that way? In pretty much any console app, when you use an input command, it knows to sit there and wait until the user has entered some data ending with a linebreak (‘enter’) character.

Formally in programming this is known as an ‘event’. This is any change in state of the compiler’s environment; an event is often user input but doesn’t need to be. It can be a mouse click but it can also be the return of data from a network call or two objects colliding in a video game.

In a simple procedural program the only way to check for an event is to create an endless loop and check repeatedly 30-60 times a second. It’s not just Scratch that does it this way. Processing (and Processing JS in Khan Academy by extension) has the draw() function, which is just a forever loop. Greenfoot has the act() function, same thing. Even Arduino C is centered around the loop() function.

Except for the Arduino, all these are primarily game-creation engines. But real programmers rarely use a continuous loop like that. Most programs with user interaction are instead event-based. This means you create a handler that responds to an event like a mouse-click or key press. In JavaScript, for example, it’s something like this:

document.getElementById("myBtn").addEventListener("click", displayDate);

But that’s advanced programming! You can’t expect a simple program like Scratch to have event handlers. Oh yeah? How about this:

When (space) key pressed - Move 10 steps
An event handler in Scratch!

If you put in the above, it works out of the box. No Green Flag Clicked necessary. Oddly, I always thought of this as the more “basic” approach, probably because there is nothing to “start” the program. But really it could be seen as the more sophisticated approach. They have the start of full event-driven programming. Imagine if they had a block like this:

On event ( ) do:
The event handler Scratch should have

With something like this you would probably still have a few things stuff in the forever loop, but almost everything else – key presses, mouse clicks, collisions, changes in variable values, appearance and disappearance of sprites, etc. etc. – could depend on event handlers. Ideally there would be something to “turn on” the event handlers too, whether a green flag clicked or whatever. There is no reason that couldn’t be in there.

But what difference does it make? Why is the forever loop so bad?

Well, for one thing, if you ever want to teach any other kind of loop it is really difficult to come up with a way to work it in, because it’s already looping. If you try to loop something inside that, it will stop all the rest of the action of the sprite. If you want to iterate, or have a conditional loop, you have to kludge it by creating a counting variable or condition and checking it repeatedly in the forever.

But in an event-driven program with multiple different event “threads” (weird, Scratch has threading too!), other handlers could respond to different events while a previous thread is still executing. This gives you an opportunity to put different kinds of loops in.

More importantly, though, it would give students a better idea of how most programs actually work. They could create an interactive environment like a modern web page.

Also, you will help them understand that a loop that repeats forever without a built-in interrupt condition is normally a really bad idea. Really there usually is some kind of interrupt, whether the stop sign or the pause button in Greenfoot and so on. But that’s outside the program the students are writing.

More importantly, we could get away from the idea that the only reason for programming is to make video games. We’re never going to get anywhere with coding education until kids start making programs that do real things, not just play.

Leave a Comment