the jsomers.net blog.

Should we cool it with the historical present?

On podcasts it's pretty common to hear something like this:

So Alexander Hamilton has just finished law school, and he's trying to make a name for himself. He's only been in New York a few years. So he takes on this case...

The problem with the past tense ("Hamilton had just finished law school, and was trying to make a name for himself") is that, very subtly, it preserves the distance that history already has. Old worlds can feel unreal. The "historical present," as deployed here, invites you into Hamilton's shoes. It's the rhetorical equivalent of that transformation that Peter Jackson pulled with World War I footage in They Shall Not Grow Old. At its best, it makes history feel... present.

But you've got to pick your spots. The historical present might be valuable when you're describing a scene---a moment---and an individual acting in it. It can make those moments vivid. But if you just use it willy-nilly anytime you talk about the past, it's confusing. After all, it's the wrong tense.

I've found that the New York Times's Daily reaches for the historical present almost as if it were against the style guide not to. And yet this is a podcast that normally takes such great pains to be clear.

Here's an example from an episode about the reaction in Wuhan to the coronavirus outbreak. The host, Michael Barbaro, wants to get the reporter to talk in the historical present. The reporter sometimes obliges, but sometimes swings to the past tense. The result is a muddle:

MICHAEL BARBARO
And what is the scene at the airport?

AMY QIN
The scene at the airport was a little bit frenzied. [...] So I'm in the airport lobby and I'm waiting for my flight. [...]

MICHAEL BARBARO
So what happens once you land?

AMY QIN
So once I land, I find that I am at the Miramar Marine base in San Diego, California. [...] And I've never seen people come together like this before---and people were so upset about his death.

MICHAEL BARBARO
And what are they saying?

AMY QIN
A lot of people were posting candle emojis and other kinds of remembrances for Dr. Li.

For a while, it still works. But jumble tenses long enough, and the timeline becomes genuinely hard to follow:

AMY QIN
So the reaction is really remarkable. [...] It was so clear that this was something that had really tapped into the frustration that was happening.

MICHAEL BARBARO
And what do you make of those reactions? Because it feels like it no longer is really just about this virus and the way that it was handled?

AMY QIN
Yeah so at this point, it is clear that this is becoming so much bigger than just the virus. [...] People in China are already used to a pretty high level of censorship, but when it comes to censoring a warning about public health, that goes too far. And the reaction is so overwhelming that the government quickly realizes that they need to do something. And that's when we see China's leader Xi Jinping come forward out of the shadows and try to take control of the situation.

Barbaro's first question---"What do you make of those reactions?"---is ambiguous. Does he mean, What do you make of those reactions today, right now, as we're speaking, or, What did you make of those reactions at the time? He means the latter.

This kind of miscue happens often when you use the historical present to refer to the recent past---because what tense are you supposed to use to refer the actual present?

Just yesterday I was listening to another episode, this one about kids returning to school amid the Delta variant. Once again, the host, Sabrina Tavernise, tried to foist the historical present upon the guest. Once again, perhaps because that felt so unnatural, the guest only halfheartedly went along:

SABRINA TAVERNISE
Richard, what happens when the Delta variant starts surging in Arkansas?

RICHARD FAUSSET
So, Arkansas, like most states, saw this really nice trough with very low numbers of new cases that went from the spring into the early summer. The whole idea of wearing a mask starts to fade into the background. And life starts to kind of return to normal. But then Delta hits in the summertime. And you started to see [...] And this vaccine hesitancy became [...]

The two continued mostly in the historical present, sometimes switching tenses like this, gradually narrating events until the timeline got closer and closer to now. Fine. The real trouble came when the reporter wanted to talk not about specific events but about broader themes:

RICHARD FAUSSET
So the governor is going around the state and, particularly recently, we've seen some of the vaccination numbers go up in the state. But it's still lagging compared to a lot of states. And in the meantime, the beginning of school is looming ever larger. [...] And it kind of rolls into this big ball of concern about how kids are actually going to be able to go back to school safely. And it's that concern that really brought the question of masks in school back to the forefront of the conversation in Arkansas.

The "particularly recently" makes it sound like we're talking about where things stand right now; the last sentence makes it sound like no, we've been setting something up in the historical present. It's hard to parse.

I'm not cherrypicking; the Daily does this in almost every episode. That's because Barbaro pushes the conversation that way:

This tense is in the air; when you start listening for it, you hear it everywhere. On the BBC's In Our Time, the host only occasionally nudges his guests into the historical present; mostly they go there themselves. Often it works; sometimes it doesn't. On an episode about the Siege of Paris, the group is happily using the historical present throughout. Here's a typical example:

JULIA NICHOLLS (40:25)
If we look at the event itself, it almost has an outsized legacy compared to what the event is. [...] It's taken up by various different international left movements [...]

Later in the episode, the host, Melvyn Bragg, finds that the present tense has been burned talking about the past:

JULIA NICHOLLS (44:30)
I think that the Communards also saw this as a continuation of a battle that had been going on since 1789 [...] It was their duty, it was an obligation to fight against those people.

MELVYN BRAGG
What do they think about this in France?

ROBERT GILDEA
What do they think about it NOW?

MELVYN BRAGG
Yeah

I love the historical present---I've used it a few times in this post---but I wish it were deployed more thoughtfully. It's great for narration, less so for exposition. It works well for the far past (the Triassic, say), when there's no chance of ambiguity, but it can make a mess of recent history. It's especially fraught when you want to mix timeframes, like on podcasts that discuss the news or the legacy of historical events.

When in doubt, is it so crazy to use the past tense to describe the past?

Introducing Five’Em, a Texas Hold’Em variant

The game of Five'Em was invented by two friends of mine, Ben Gross and Rich Berger, to combat Hold'Em fatigue.

The rules are simple: You're dealt five hole cards instead of two, and after each round of community cards comes out (starting with the flop), you discard one of these extras. After the river is dealt, and you've discarded your third extra card, you end up with a classic Hold'Em hand.

Five'Em has some of the pre-flop dynamics of Omaha, in that a seemingly excellent hand -- say, a pair of kings and a pair of tens -- might actually lead to some hard decisions, because you'll only be able to hold on to one of those pairs. But since you always seem to have decent shot at a good hand, it's hard to imagine folding early.

The extra decision on each "street" forces you to think more explicitly about odds and outs. It's one thing to be on a straight draw, and another to weigh playing for that draw against, say, holding on to the top two pair.

It's as if you're playing multiple people's Hold'Em hands simultaneously, with the twist that you're forced to fold one at each turn. It's more fun than the classic game because you've always got more chances -- but of course your opponents do too, which means you've got to adjust your sense of a winning hand.

As a one-time offer, we're waiving the $15 licensing fee -- if you've got a standard deck of cards, feel free to start playing!

The three-page paper that shook philosophy: Gettiers in software engineering

In 1963, the philosopher Edmund Gettier published a three-page paper in the journal Analysis that quickly became a classic in the field. Epistemologists going back to the Greeks had debated what it meant to know something, and in the Enlightenment, a definition was settled upon: to know something is to have a justified true belief about it:

  • justified in the sense of deriving from evidence
  • true, because it doesn't make sense to "know" a falsehoood
  • belief, i.e., a proposition in your head

Gettier, in his tiny paper, upended the consensus. He asked "Is Justified True Belief Knowledge?" and offered three cases---soon to be known as "the Gettier cases"---that suggested you could have a JTB about something and yet still we would want to say you didn't know it. For that, he earned lasting fame, and his paper generated a literature all its own.

A Gettier case

Supppose you're standing in a field and off in the distance you see a cow. But suppose that what you're actually looking at isn't a cow, it's just a convincingly lifelike model of a cow made out of papier-mâché. You're not seeing a cow, you're seeing the model. But then finally suppose that right behind the papier-mâché cow is a real cow!

On the one hand, you have a justified true belief that "there is a cow in the field": (1) you believe there's a cow in the field; (2) that belief didn't come from nowhere, but is justified by your seeing something that looks exactly like a cow; (3) and there is, in fact, a cow in the field. Still, we wouldn't want to say that you know there's a cow in the field, because in a sense you got lucky: by a strange coincidence, there happened to be a real cow there---a cow you knew nothing about.

In software engineering

At my old company, Genius, the CTO---who'd studied philosophy as an undergrad---was obsessed with these Gettier cases. He called them "gettiers" for short. So we used to talk about gettiers all the time, no doubt in part just because it felt clever to talk about them, but also because when you're a programmer, you run into things that feel like Gettier cases with unusual frequency. And once you have a name for them, you start seeing them everywhere.

Here's a recent example. I was working on a web application that used a client-side framework that had been developed in-house. My app was a little search engine, and in my latest pull request, I'd made it so that when you hit Enter in the search field, the field lost focus, so that folks who like to browse the web via their keyboard wouldn't have to manually escape from the input box.

When I released the new version, I noticed that I'd broken the autofocusing of the search field that was supposed to happen on pageload. I started poking around, only to discover that I couldn't seem to get the correct behavior back. No matter what code I changed, which lines I commented out, how many times I hard-refreshed the browser, etc., I couldn't get the autofocus to work.

What had actually happened is that a coworker of mine had made a change to the framework itself, which changed how certain events were bound to the root DOM element, and as a result broke the "autofocus" attribute. At some point, I did a routine rebase on top of this change (and many other unrelated changes). Which meant that when I deployed my little pull request, I was also deploying a bug I had nothing to do with---one that ended up breaking autofocus. It only appeared as though my changes caused the problem, because I'd edited some code having to do with focus in the search field.

Note that I had a justified belief that "the pull request I just deployed broke autofocus on the production site," and in fact my change did break it---making the belief true. But the break actually happened for a completely different reason!

(Yes, I should have caught the bug in testing, and in fact I did notice some odd behavior. But making software is hard!)

Here's another example. (This one's from a long time ago, so the details might be a bit off.) A user once reported that on-site messages were no longer generating email notifications, and I was asked to investigate. Soon, I discovered that someone had recently pushed a change to the code that handled emails in our web app; the change seemed to introduce a bug that was responsible for the broken behavior. But---gettier!---the email service that the code relied on had itself gone down, at almost the exact same time that the change was released. I could have had a JTB that the code change had caused the emails to stop delivering, but still we wouldn't want to say I "knew" this was the cause, because it was actually the service outage that was directly responsible.

A new term of art

A philosopher might say that these aren't bona fide Gettier cases. True gettiers are rare. But it's still a useful idea, and it became something of a term of art at Genius---and has stuck with me since---because it's a good name for one of the trickiest situations you can get into as a programmer: a problem has multiple potential causes, and you have every reason to believe in one of them, even though another is secretly responsible.

Having a term for these tricky cases allows you, I think, to be ever-so-slightly more alert to them. You can be a better developer this way. As I've spent more time writing software, I've gotten better at sensing when my assumptions are probably wrong---when something gettieresque might be going on: have I forgotten to clear the cache? Am I working off the wrong branch? Am I even hitting this code path?

Software is a complex and ephemeral business. More than most people, developers are daily faced with bizarre epistemological problems. It helps to be able to distinguish a cow in the field from, well, a gettier.

DocWriter: the typewriter that sends its keystrokes in real time to a Google Doc

For years I’ve wanted a writing machine that would combine the best parts of a typewriter and a word processor. After months of tinkering, my friend Ben Gross and I just finished building one. We call it the DocWriter. It’s a typewriter that sends its keystrokes in real time to a Google Doc.

The beauty of a typewriter is that it propels you through a piece of writing. You can't tinker with phrases, so you get used to laying down paragraphs. Your mind, relieved from the micromechanics of language, applies itself to structure, to the building of sections and scenes and arguments. When you're done you end up with something whole, even if it's imperfect: a draft that reads from start to finish and that you can hold in your hands.

A word processor, by contrast, turns revision into a kind of play. This is true not just for the fine wordwork that comes right before publication, but for the big stuff, too, like when you want to move sections around, or see what a story looks like without a side character. Doing this kind of thing on a typewriter would be a nightmare -- to say nothing of the simple fact that your words will have to be digitized at some point and it's just not practical to scan them or type them up off a sheet of paper.

The idea behind the DocWriter is to be a bridge between these tools so that each serves its purpose: the typewriter, to create the building blocks of a piece of writing, and the word processor, to make the most of them.

How we built it

The DocWriter is actually pretty simple: we took a Brother SX-4000 electronic typewriter and spied on its keyboard switch matrix by soldering a few wires onto the main circuit board; we ran those to a Raspberry Pi 3, which runs a C program that reverse engineers the signals; we pipe this data over ssh to a computer program running in the cloud; that program maps the signals to keystrokes and runs a headless web browser that types the keys into a new Google Doc.

From the user’s perspective, you’re just using a typewriter. The Raspberry Pi is hidden inside it (the blue box in the image above), and it draws power from the typewriter itself, so there’s no extra cord. When you turn on the typewriter, it boots the Pi, which connects itself to your WiFi network, and runs the program that listens for keystrokes and pipes them to the cloud. You know that the DocWriter is ready once you get an email from Google Docs saying that the machine has shared a new document with you.

We're indebted to numist, who turned the same model typewriter into a teletype using software much more sophisticated than ours. That work made our project seem doable, and gave us many clues about the kinds of problems we'd encounter along the way.

There were, indeed, many problems: we had a surprisingly hard time getting the case off the typewriter when we first bought it; by unlatching the keyboard, we inadvertently triggered a condition where the motor would endlessly grind up against the case, and nearly convinced ourselves we'd broken the machine; the early versions of our controller code erroneously piped data to the typewriter, causing all kinds of weird behavior; we built the whole setup three times, first on an Arduino and then on a Raspberry Pi Zero, before settling on the Pi 3; we had a bad connection on a wire that caused some keys to fail; we wrote elaborate code to compensate for noise on the lines, before realizing that we could use pull-up resistors to more or less eliminate it entirely; we spent nearly a full day just installing a headless web browser that worked; and we had to rewrite our main control code about a dozen times.

In the end, though, the setup is elegant: along with wires for power and ground, we had to solder just 16 connections onto the pins controlling the keyboard switch matrix on the typewriter's circuit board. The rest is software, most of which does exactly what you'd expect. The hardest code to write was the controller to read the raw signals from the typewriter. But we got it down to something with nearly perfect behavior that's also pretty minimal (especially when you ignore special cases for the Shift key):

#include <wiringPi.h>
#include <stdio.h>
 
int main(void) {
  wiringPiSetup();
  setbuf(stdout, NULL);

  int scanPins[] = {5, 22, 10, 11, 26, 27, 28, 29};
  int signalPins[] = {13, 12, 3, 2, 0, 7, 24, 23};
  
  int i = 0;
  int j = 0;
  for (i=0; i<8; i++) {
    pinMode(scanPins[i], INPUT);
    pinMode(signalPins[i], INPUT);
    pullUpDnControl(scanPins[i], PUD_UP);
    pullUpDnControl(signalPins[i], PUD_UP);
  }
  
  int keyDown[8][8] = {
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0}
  };

  int lastI;
  int lastJ;
  int sameKeyCount = 0;
  for (;;) {
    for (i=0; i<8; i++) {
      for (j=0; j<8; j++) {
        if (digitalRead(scanPins[i]) == LOW && digitalRead(signalPins[j]) == LOW) {
          (i == lastI && j == lastJ) ? sameKeyCount++ : sameKeyCount = 0;

          if (sameKeyCount > 50 && keyDown[i][j] <= 0) {
            printf("%d,%d\n", i, j);
            keyDown[i][j] = 50;
          }
          lastI = i;
          lastJ = j;
        }
        
        if (digitalRead(scanPins[i]) == LOW && digitalRead(signalPins[j]) == HIGH) {
          keyDown[i][j] = (keyDown[i][j] - 1);
        }
      }
    }
  }
}

A Ruby program in the cloud takes the output of this program (raw indexes like "6,0" for spacebar, or "5,3" for "j") and maps them to strings, which it sends to a Google Doc using the watir gem for driving headless web browsers.

Can I get one?

For now this is just a one-off project, and we sadly won't have the bandwidth to make others—except maybe for an exorbitant and unfair price (like $10,000).

Most book clubs are doing it wrong

The standard way to run a book club is to have everybody finish the book before meeting to talk about it. You have one meeting per book. The discussion goes on for one or two hours before it runs out of gas, and then the group picks the next book, and you agree to meet in another month or six weeks.

You would never run a class this way, because it practically minimizes the value that each participant gets from being in the group. The problem is that there's no time to cash in on anyone else's insights. If someone says something in the meeting that reframes how you think about the book -- they suggest that Holden is lying, or that Kinbote wrote Canto IV; they tell you to read Portrait first, so you can understand Stephen's double bind; they claim that Offred's tale is a series of transcripts, not journal entries -- well, now it's too late, because you've finished reading the book and you're probably never going back to it.

What makes a class useful is precisely that it lets you compare notes with your classmates along the way, to float your working theories about a book and see how they sound to others. It's not a retrospective, or not merely one -- you're equipping yourself for the rest of the reading.

This is true not just of frameworks or theories or whatever but of little nuts-and-bolts stuff, too, like when someone points out a reference that you missed or helps you savor some language that you blew right by the first time. That kind of thing is especially valuable when you're reading a difficult book.

My book club started four years ago to read Infinite Jest. There were five or six of us; we had all tried, and failed, to read the book on our own. We met every week and read about fifty pages for each meeting -- five or six hours' worth for a book that dense. If you were out of town, you tried to call or Skype in, and you were forgiven for missing a few sessions, so long as you more or less kept up with the reading.

Since then we've run just about continuously, every week, week in, week out, for four years. We've read other hard books, and easy ones too, and no matter what, we've always split the reading into at least more than one meeting, because isn't that after all how you make use of those other minds? Book club, for us, isn't about reading the same book; it's about reading a book together.

We try to keep the reading to about the amount you can do in a few hours on a Sunday afternoon. Weekly book club has become a fixture in our schedules, an institution like family dinner, though it's not uncommon for someone to skip a whole book, say if they're traveling a lot or right after they've started a new job. The idea is to make book club less an obligation than a sort of pleasant presence in our lives, this thing that's always there.

Some books don't really demand so much attention, and our book-talk during those sessions quickly devolves into banter. But most of the time the discussion lasts a full hour before it runs out of steam, naturally, the way almost all meetings seem to.

That's another reason to break a book into pieces: better to have too little to fit into a session than too much; god forbid you read something complex and demanding -- do you really want to spend three hours in the unpacking, or to have the session break down before the unpacking's done? And what are the odds that you'll even remember most of the book by the time six weeks pass?

Good books are almost fractally deep: you find whole worlds wherever you look, and no matter how far in you zoom. Breaking a book into multiple meetings makes the most of this fact. It gives you space to dwell -- on a page, even on a single word -- without feeling like you're wasting anyone's time. No: that's what a book club is for, not to sum up what you've read but to live inside it.

I don't know why more people don't run book clubs this way. I think part of it is that they've never tried; the very concept of a book club seems to imply a one-book-per-meeting structure. Others hear the idea of meeting weekly and think who has the time?

I would say that anyone who loves books has the time. A book club run in the standard way isn't efficient or practical -- it's just a good opportunity wasted.