Programming as a Vehicle for Math
Programming as a Vehicle for Math
In March 2020, I gave a talk at Math for America, an organization that fosters professional development for K-12 math teachers in the New York City area. It was part of my PIM "book tour," though for this talk I focused on showcasing computers as a tool for creating things you care about, while framing the obstacles to creation as a perfect time to introduce mathematics. Most of the talk is examples of this.
The MfA organizers never posted my talk online, and at this point I've lost hope that they will (thanks, Covid). So I'll recap the content of the talk, linking to my slides (click there for nice images and gifs) and the transcript I prepared in advance of that talk. This post will summarize the main ideas and provide some extra color.
Math lets you write cool programs. And it does it in a way that is fundamentally different from any fashionable programming topic of the week. Most programs that rely on mathematics have, at their core, an algorithm or formula that is indecipherable without learning the math it's based on. Bit somehow it's simple once you understand the math.
This has been a touchstone of my career, and my first "revelation" about math was in high school. I wrote about it at length here. I took two years of programming classes, and was blessed to have a teacher who gave us sufficient room to explore and play. My big project was a 2D zombie-shooting game. In that game I wanted to make a double-helix shaped "wave gun," which boiled down to rotating a sine function (parameterized by time/frame) around an arbitrary angle.
I spent two weeks trying random formulas with guess-and-check (compile and run and watch things go awry). After failure and frustration, I asked my math teacher for ideas, and he showed me the pre-calculus version of the 2D rotation matrix formula. It worked like a charm, I had no idea why it worked, I had a blast playing with the result, and it planted the seed in my mind that math was useful and elegant. Repeat this and you get a formula:
- Work on something you care about.
- Try and fail to solve it.
- Discover or be shown a math thing that will help.
- Incorporate it and be amazed.
Another way to put it is how Daniel Pink—former lawyer and political speech writer, now self-help author—puts it. To be happy, Pink says, people need a triad of autonomy, mastery, and purpose. In my case, the purpose was making a game and having fun. Programming provided autonomy to do that. And math provided a path to mastery.12
Nothing about my story is specific to math. If you're passionate about woodworking and you face some problem, then discover a new technique or a useful tool that makes your problem effortless to solve, you'll remember that forever. But computers put a unique spin on this. Because at the bottom layer, math is the only interface we have for telling computers what to do. People who say otherwise are usually referring to an abstraction hiding the math, beneath which someone else has already worked out the mathematical details.
In a GUI, for example, the mouse pointer lives in a coordinate system completely imagined by programmers. The computer doesn't see the screen or the icons. It's all an internal representation, and it's modeled and manipulated by math. Once you're in the computer's underbelly—that is, once you need to do something truly custom or new—you will find a need for math. Learning opportunities appear to be ripest when one uses an application that has a basic interface, but allows adding sophistication for complex tasks.
SVG is a fantastic example, and Phil DeOrsey ran a lovely math circle demonstrating this using a pen plotter. Students would write equations in GeoGebra to make symmetric repeating patterns, export the resulting diagrams to SVG, and send them to the pen plotter to draw on paper. You can get even fancier with a laser cutter (students could make their own wooden coasters, for example), and at the highest end there's 3D printing, CNC routers, and metal machining.
SVG is so perfect for layering math because while it provides the basics of circles, rectangles, rotations, and color, if you want to do anything sophisticated you'll quickly find the need to learn about Bezier curves and matrix transformations. And SVG mostly requires the user to keep track of relationships between objects.3 In the more advanced applications, 3D printers are all based on shape files (STL) that define nothing more than a collection of triangles that "triangulates" (approximates) a smooth surface. While most 3D modeling applications handle the details of converting a schematic to triangles for you, if you want to do something more complicated, you could write a program that generates the STL file directly, or use a more programmatically-oriented 3D modeling program like Open SCAD.
Another example is music. There's this awesome program called Sonic Pi which is a simplified IDE for writing programs that play synthesizer music. In Sonic Pi you write "live loops" that are like separate tracks repeating to compose the final piece. Sonic Pi is nice because, like SVG, it has some basic built-in concepts like notes and scales—which already provides a huge range of topics to discuss like how sine curves relate to sound and why certain notes sound good together—but to make fun and original music, you use lower-level APIs.
You can, for example, sample tracks, which requires you to scale and align them. With a 4 second sample and a 5 second sample, to align them you use the Sonic Pi API to slow or quicken one track by a percentage. This, of course, must be computed manually or dynamically by understanding the formulas for percentages. The more advanced student might want to know what sorts of patterns make for good beats, and there's a ton of literature out there about rhythm and music and math. And then there's the classic Attack Decay Sustain Release (ADSR) mechanism to make sounds feel dynamic. This is literally a piecewise function, one of the most boring topics in all of high-school mathematics. All the while you're making fun music.
In the MfA talk my next example was about how you can write programs to model simple phenomena in complex systems around you. Like the now-tired firefly synchronization model, or the Schelling model of segregation. I was less enamored with this section even when I wrote the MfA talk, since so much of bad math is actually bad modeling of real-world processes. And what student cares deeply about firefly synchronization, and what good really is that for? It's not like making art or music or games that most kids naturally find fun.
But 2020 delivered a fantastic counterexample
when a popular YouTube streamer was caught cheating at Minecraft speedruns.
They caught him by comparing known
"drop rates" in Minecraft
(i.e., RNG probability thresholds for some event to occur
that is needed to complete the game),
and developed a model to evaluate the probability
that the streamer could have gotten as lucky as he did
to see the events occur so quickly.
Turns out, that probability was vanishingly small—10^-13
chance
that anyone in the Minecraft speedrunning community would
have gotten as lucky as he did.
And later it was revealed he was (unwittingly, he claims) using a mod
that increased the game's drop rates.
The paper linked above is full of nice probability concepts, calculations, and a lot of adjustments for the fact that the RNG used in Minecraft is not perfectly random. And of course, it comes with a C program to repeat the calculations. This is far better motivation (for someome who loves Minecraft), a far better education in the usefulness of the topics, and a far richer source for discussions than any contrived modeling activity could provide. I also happen to think that Minecraft in general is a fantastic way to get someone into computer programming, but that's a different discussion. If I were to write the talk again, I'd be torn to either include this example, or find something else, because Minecraft is a bit too "boy's club" for it to be practical as a lesson in a math class. For individuals who are already invested in Minecraft though, it's excellent. And that's my point. The hardest part of math class—motivation—is already solved.
In the rest of the talk, I gave examples of lessons I wrote for programming students that focused on introducing math. The core ideas there were to create a playground for experimentation, provide simple boilerplate code, have the basic assignment change the code in a predetermined way, and make the rest of the assignment open ended (e.g., add any new feature that interests you).
A simple example I used on real students for a few years, with success, was to make a very simple "game" involving balls bouncing around a 2D window. The initial bouncing was dumb (not vector based position/velocity/acceleration). The first task was to make it vector based. The second task was to make it bounce against the walls. The third task was to make a mouse click "kick" it. The fourth task was to "add any feature you like", and my demonstration was to add a feature that spawned more balls, and play an explosion animation when I clicked a ball. Many students did simple non-mathy features. The students who were interested in math did things like give the balls proper angular momentum, or bounce into each other, or change gravity. A followup assignment used a boilerplate minimal Minecraft clone (in only a few hundred lines of Python!), and asked them to add similar features.
Another example I used (which I had not actually tried) was to create custom Instagram filters. Starting with a GUI that you can drag-and-drop blocks to make simple filters, to coding in Spark AR, to making your own apps that involve AR features of a phone. The main point is that simple app filters involve applying math functions to images, like sine functions that goofily distort a face. The most sophisticated filters use neural networks to detect faces, or modify facial features dynmically. I suppose today it would be custom TikTok filters, and I bet an assignment to use math to make custom TikTok filters would be hugely popular among K-12 students.
Of course, there are a ton of obstacles to implementing any of these ideas in a classroom. The first few I can think of off the top of my head:
- Teachers don't know how to program or have time to learn it and the ecosystem and tons of applications of math to music and art and Minecraft.
- Even if the above were solved, you can't easily write lesson plans that allow everyone to do their own custom math thing for the thing they care about, because schools are industrial pipelines where every student is suppoed to leave with the same Student Learning Outcomes.
- Even if the above were solved, the amount of math you'd learn this way is relatively small, because you'd only use it for the "mastery" part and you'd spend most of your time making songs or games or TikToks. School administrators would never accept this.
In my opinion, these problems are not problems with the approach, but problems with the educational system restricting learning to a narrow band of experiences and partitioning it by subject. One of the great things that my high school programming teacher did was treat programming like a portfolio class, and let each student work on whatever they wanted, so long as they could prove at the end of each quarter that the project they worked on demonstrated that they learned to write programs. Every student picked something related to their interests. And the teacher didn't always know everything the students were trying to learn. He also didn't have to learn it on the spot! He was merely an excellent rubber-duck for debugging, and a decent pair programmer. Having a computer to use to do guess-and-check was a big enabler here, and he always slyly made it seem like he knew how to solve the problem but wanted to let the student figure it out.
And as far as only learning a little bit of math, I think this should be considered a good outcome of schooling. In today's world, we cram math into students brains and unless they go on to be engineers it's invariably wasted. At best it has to be relearned in context of some advanced schooling (e.g., stats for doctors). As a result, math is mostly hated and yet weirdly idolized as a black box. I'd prefer if everyone got it in their head that math can be extremely helpful if you dig into it, and if everyone had a good example to share that helped them, even if in the end they decide math and critical thinking isn't how they want to spend their careers.
-
The game also had a bunch of other, more boring math topics that one might also consider in the same "mastery" loop, just at a smaller granularity. I had to employ parametric functions, some basic position/acceleration/velocity vector math, and use arctangent to "draw" the player, whose sprite was two circles lying tangent to each other (the bigger circle the "player" and the smaller circle the "gun"). Somehow these weren't as astounding to me, and it's likely because I had already seen them before having a problem to solve them with. ↩
-
Another thing I think is miraculous is that the Java code I wrote in 2006 still runs in 2021. Everyone thinks Java is boring and cumbersome, but they have demonstrated they care about long-term support. ↩
-
Another subtle, but critical aspect of SVG and many interfaces like it, is that it forces you to write your equations in "standard form." I.e., if you want to describe a line, you don't get to use "point-slope" form, you have to use "pick two endpoints." In other words, if you want to draw a ray emanating from one point, you need to convert from "point-slope" to find where the second point should go based on how big your canvas is. To convert to the "standard form" required by the computer, you must do the types of rote calculations math students have whined about forever. But in this case it matters because you're using that skill to make art! And of course, the math only ramps up as you get more into graphics and design. I gave a few more fun examples in the talk of math in art and design. ↩