Origin Story

David Rea
7 min readNov 29, 2022

--

In 1990, relatively fresh out of college, my undergraduate-level expertise in nuclear arms control in much less demand than anticipated, I found a job in an advertising agency with an oddball group developing some software for marketing. One of my bosses, Michael Grandfield, gave me a book on LISP programming and said “Teach yourself to program so you know what we are talking about.”

(The next day he also gave me Douglas Hofstadter’s “Gödel, Escher, Bach” and said, “And read this because it’s interesting.” Cool boss, huh?)

I had done a little bit of BASIC programming in the 10th grade, thanks to my math teacher, and used that knowledge again in a college astronomy class to solve a couple of problems that were beyond my math skills. But LISP was a whole new animal. Unlike the simple (simplistic?) structure of BASIC, LISP involved strange concepts like nesting and recursion. I loved it.

Here’s a canonical example of a LISP program, to compute factorials recursively:

(defun factorial (N)
"Compute the factorial of N."
(if (= N 1)
1
(* N (factorial (- N 1)))))

Not long after, Michael started giving me programming tasks. The first one was to graph some data, specifically a visualizations of some chi-squared analyses. None of the spreadsheets of the day…of which Lotus 123 was the gorilla…did exactly what he wanted. But one upstart spreadsheet, Wingz, included a macro language with 2D drawing ‘primitives’: lines, squares, circles, etc.

After I got the basic plots working, with a menu to let you choose which variables you wanted to look at, I saw that when the inputs were changed and the graph refreshed, I couldn’t tell how the new plot related to the old plot. That is, when the points instantaneously jumped to new positions I lost information.

What I needed was a smooth transition, so that the points would drift to their new locations.

That weekend I had my first experience being so immersed in programming that the physical world receded. I forgot to eat, without being hungry, and was surprised when the sun came up Sunday morning. But Monday at the office I had a killer demo for my two bosses. I remember them looking at the screen, looking at each other, looking at me. Michael had a gleam in his eye and a funny, knowing smile.

From that day, my job description changed to full time programmer.

Next up was to graph some statistical data the team had generated using SPSS. The statistical technique used was “correspondence analysis” that computed how similar data items were…in this case demographic segments…and Michael wanted to display it in a kind of radial scatter-plot.

That was now easy for me, but when I saw the result I realized that once again I wanted to add something more: I wanted to know the magnitude of the plot points, that is, how big of a market each of the demographic segments represented. I tried plotting them as circles, with an area proportional to their magnitude, but realized that doing so distorted the data because my eye and brain wanted to judge proximity from the edges, not the centers. I needed to make all the points the same size.

Next I tried using color to represent magnitude, but that was also dissatisfying. Although the data was present, it still required conscious interpretation; I can’t remember what colors I used, but my brain still had to think about “more red” meaning “larger market.”

No, what I wanted was a third dimension. I wanted to tilt the whole graph, so that each point would have a height, like a building, and the clusters of skyscrapers would represent the densest markets.

There was just one problem: Wingz did not have any 3D drawing functions, only 2D.

However, I knew a bit about 3D drawing because my dad was an architect and had taught me how to draw isometrically. I knew that a 3D drawing was an illusion created by 2D shapes, polygons. For example, this “cube” is just three parallelograms; our eye interprets it as 3D.

Add some shading and it really pops:

But I didn’t know how to do this in code.

Although I didn’t think of it this way at the time, my challenge was that I could intuitively draw in 3D, but I couldn’t describe it. I wouldn’t be able, for example, to talk to somebody on the phone and tell them how to do it. And if I did show somebody how, it would be a specific example, like a cube. I had never thought about what the general instructions were. It’s just something I understood in my own head but had never thought about as a process.

And really programming is the art of giving generalized instructions. It’s about seeing the pattern(s) in a task, and describing them with two competing objectives:

  1. As concisely as possible.
  2. With enough flexibility to apply to all necessary cases.

I decided to start with just a simple cube, and after drawing a number of them and staring at them I made no progress.

Next I cut up a manilla file folder, folded and taped it into a cube, and held it under a desk lamp, watching what happened to its shadow as I turned it this way and that. In my mind I tried to imagine how the six sided blob on my desk was really three separate polygonal shadows, cast by the three faces of the cube facing the lamp:

Eventually I realized that if I just rotated the cube around one of its axes, and tried to focus on just the one face of the cube that was facing the light. It’s shadow was the square:

As I rotated the cube, the shadow from just that face (the darker rectangle) would get skinnier, even though the shadow from another face (the lighter rectangle) would grow:

As I approached 90 degrees, the top face…now on the side…would eventually disappear:

The width of the shadow, as a percentage of the actual size of the cube, was a function of the angle of rotation. I thought to myself, or maybe I said out loud, “At zero degrees it’s a hundred percent; at 90 degrees it’s zero percent.”

That seemed familiar. That sounded like what Mr. Bergofsky had tried to teach me in high school. Trigonometry.

Then the menomic popped into my head. “Soh Cah Toa.”

I borrowed a scientific calculator from our statistician, plugged in some numbers, scratched my head in confusion, remembered that calculators don’t use degrees, figured out how many radians in a circle, plugged in some more numbers, and was finally satisfied that I understood sines and cosines.

Then I got to coding.

After many mistakes, lots of frustration, endless debugging, and occasional steps forward, at the end of a week I had a perfect 3D (isometric) cube slowly rotating on my screen. I probably spent an hour just staring at it.

I refactored my code into a generalized library, and built my 3D visualization. Honestly it wasn’t as useful or amazing as I expected.

But I learned two things that permanently altered my trajectory.

First, it turns out I love trigonometry. Despite the (intentionally?) obfuscating terminology I see the simple, beautiful truth in circles and triangles, and I use it all the time in programming.

Second, the reason I was able to see it for what it is, and to deeply understand it, is because I needed it to build something. Instead of reading a meaningless problem, punching numbers into a calculator, writing an answer on a piece of paper, and waiting a few days to find out if my number was the correct number, I made something cool. If my trigonometry was wrong, I immediately saw it on my screen, and it was up to me to figure out…to debug…the problem.

All math should be taught this way, I concluded. From there it was almost inevitable that I ended up back in graduate school, and then on to teaching.

--

--