Explaining Event-Driven Programming in the context of the Structured Programming Theorem I'm a retired college teacher.  I've been asked to "teach coding" to a dozen very bright seventh-graders using the Micro:Bit kits the school has on hand.  I have a total of seven contact hours available.  In three hours, we've learned about algorithms, variables, and operators.

On Tuesday we'll write a program for "red light / green light" and learn the difference between sequence and selection.  The following week we'll do something with a loop and I'll add "iteration" to the vocabulary.  While I probably won't say "Structured Programming Theorem," I was going to tell the kids that sequence, selection, and iteration are "all you need."

The trouble is, the MakeCode block language has "on-blocks" which fire when events occur, e.g. "on Button A pressed."  You can't avoid these.

So, how do I explain events, or "on-blocks" in the context of sequence, selection, and iteration?  (The best I've been able to come up with so far is that there's a hidden loop of if statements checking for events, which is probably how the on-blocks are actually implemented, but unlikely to be satisfying to twelve-year-olds.)
I don't see that there's anything to explain, because there's no apparent contradiction between a set of language constructs being "all you need", and a language having more constructs than are "needed". Languages are designed to have constructs that are useful for human programmers to easily and concisely express what a program should do, not just a minimal set of constructs for it to be possible to express programs.

It's not even necessary to explain that event-driven languages are implemented using hidden conditional statements and loops; and as Buffy notes in the comments, they may not actually be implemented that way anyway. If you want to tell your students that they could be, then I see no problem with that. But consider this:


Untyped lambda calculus is Turing complete, so "all you need" is function definitions and function application. Does that imply that conditional statements and loops must be implemented with hidden function definitions and hidden function applications? Well, no, it doesn't imply that.
The logical NAND operation is functionally complete, so "all you need" is NAND gates. Does that imply that computers are made only of NAND gates? Again, no, it doesn't.
As shown in this paper and amusingly demonstrated in this compiler, the x86 mov instruction is "all you need", i.e. any C program can be compiled to a sequence of unconditional writes to memory (at addresses read from memory). But the rest of the x86 instruction set is, of course, not implemented that way.


What I will suggest is that if you do want to mention that sequence, conditional statements and loops are "all you need", then you should add that real programming languages have more control-flow constructs than just those, because the additional ones (e.g. subroutines/function calls and return, try/catch, event loops…) are convenient.