Functions and Events Before Variables and Objects

Stop Teaching It Backwards

The AP Computer Science program and most computer science teachers today are currently introducing class-based object-oriented programming before even mentioning event-driven programming (if they ever do at all). This is a serious flaw in most curriculums. Here’s why.

Concurrency is the Queen Mother

Academics have been raving about this since before they dropped Scheme as their introductory language. They were right. It is interesting to see the entire programming world come around to that way of thinking shortly after MIT decides to make Python the main beginning language. (Sorry MIT, Stanford beat you on this one picking modern JavaScript, which is more Scheme-like than ever, and Golang.) MIT is still teaching Java to beginners.

Ok, so at this point you are wondering, “Why is this guy trashing my favorite languages?” I’m not really. I use them too (‘cept Java, which is Satan-script). It is not so much about the language as the principles that are required by current computing and industry demands and the languages that best support them.

Most software problems today are best solved by a highly concurrent language. For example, recently I had to pull down about a dozen specific sheets from a Google Sheets API call. They are all in the same spreadsheet, but the API currently requires individual calls for each sheet in the spreadsheet (if you know a way around this I will send you a beer). Anyway, I was able to write a highly concurrent function that pulls down a single sheet. Then I was able to wrap that with a Promises.All() call so that all the pulls could happen at the same time. It was drop dead simple in modern JavaScript with Promises compared to every other language right now (including my favorite, Golang). This is because the language has event-driven concurrency underlying its entire IO system, it remains the most unique and powerful aspect of JavaScript over all other languages.

Events Drive Everything

Programming paradigms are often described as a way to look at the world that allows complex programming to be maintainable and supported by multiple programmers concurrently. Ironically that very description of paradigms lends itself to the event-driven model. Each programmer has to be able to program in parallel without impacting the other and communicate (send events) about their changes and plans. The objects (bits of code they are working on) are actually secondary to the event system. It is more important to create programming practices and models that adapt to this event model than to any brittle object/class system. And yet we still teach OOP first.

[Incidentally this is why Microsoft’s purchase of GitHub—the very event-driven system that solves the biggest problem of concurrent development—is perhaps one of the most important purchases in history.]

Events are More Fun to Teach

It is not surprise that the gaming and simulation systems of today are fundamentally driven by events first, and objects. We can learn a lot about that just by looking at Unreal Engine®.

First we have a ‘thing’ and then that thing interacts with its environment. All the code is designed to do something when that event happens. In fact, in all real-time systems from a web-browser to Fortnite® there is an implicit event loop asking “can you hear me now” like bad advertisements (back when advertising was still a thing).

When … Then …

This is how even the first program a person ever learns should be taught. Rather than just blurting out “Hello world!” How about we respond to an event?

The algorithm should be: when you have the world's attention then say "Hello world."

Not even a simple command line script escapes the event-driven paradigm: when you type the command and they press enter then do what is in the command.

Event-First Instruction

It’s now my firm belief that we should be starting with an explanation of events, perhaps immediately after explaining algorithms (the recipe of steps to accomplish something).

We could certainly make a connection for those who have learned algebra. Plotting functions has events built into it: when x is 6 then set y to whatever. This follows nicely into Calculus when the intervals are reduced infinitely.

Start with Functions, NOT Variables

In the original Structure and Interpretation of Computer Programs from the MIT Press that was used for years to introduce young computer scientists to coding (and is not available for free as a PDF) the authors start with expressions and “procedures” (a word I love and still use when teaching to distinguish true functions from just a number of steps).

Then then describe operations (not operators) in terms of procedures, which is just brilliant (and will always be).

They spend an entire Chapter just describing “data abstraction” without ever mentioning “variables” or even “constants”.

Then they start Chapter 3 saying “The preceding chapters introduced the basic elements from which programs are made.” Keep in mind THEY DID NOT EVEN MENTION VARIABLES but they did frequently refer to procedures and implied that they happen in response to events (without specifically calling that out).

[I strongly recommending reading all of Chapter 3 at least. It is brilliant in explaining the real-world situation of state, why it is required, and how “assignment” fulfills the base requirement for state in the “environment model”, which has been widely adopted in every language and system including purely functional ones like Haskell.]

It’s Harder to Teach

I will be the first to admit that as I modify my lesson plans to start with expressions and procedures/functions (instead of variables) that it is challenging to help students get their heads around it. But I truly believe they will be better in the long run for wiring their brains early to events (and event handling) rather than objects and imperative constructs.

Imperative Loops are Dead

Loops of any kind are the last thing I plan to teach beginners because, honestly, they are dying out in modern program and being replaced with map, filter, reduce.

If you do not know what that means and you are responsible for modern computer science and programming instruction stop right now, grab some coffee, and make sure you master it.

Loops are a fundamental block to concurrent programming because they almost always block. The only loop that should be in most programs should be the event loop created to create an event-model in an imperative or hybrid language.

“One loop cannot hurt, right?”

Sounds like a 70s teen in a advertisement against pot (or beer if you grew up in Utah).

I’m here to say it can. You see I was raised on imperative programming with blocking IO. My brain has been wired for years to be single-threaded. I blame the first languages I was exposed to.

Today JavaScript provides ample opportunity to introduce asynchronous, event-driven mindsets from the very beginning. It is perhaps JavaScript’s greatest contribution to the world and to current and future programmers. JavaScript was the first to truly conquer the asynchronous conundrum in a very single-threaded, imperative world still focused on throwing more power at existing CPUs rather than adding more of them. Critics of early JavaScript (myself among them) have seriously just got to shut up today. JavaScript is nothing like it was and thankfully in many ways has become what Brendan seems to have envisioned having been influenced by the state-is-a-necessary-evil MIT group.

Thank you, all of you, for JavaScript and for predicting a future way before your time, one where 100s or 1000s of CPUs are in every computer, where the most important element of your paradigm is concurrency, and the key component of that the when ... then ... event model.

You were right.

Now it is time for all of us to start teaching it the right way (despite what is still popular or financially motivated *ahem* looking at you College Board).