hamster.dance blog


Have you heard the good news about NixOS?

Published 3 Aug 2020, last modified 15 Sep 2020

The Nix community logo, a hexagonal snowflake made of lambdas in two shades of blue.

After 15+ years of using various Linux-based operating systems (called distributions or “distros” in the jargon), I’ve finally found my favorite. It’s called NixOS.

At a very basic, technical level, most Linux distributions are pretty much the same. They share a common kernel (the core part of the operating system that runs and manages applications and provides them with a generic interface to the computer’s hardware), a common way of organizing files and command line interfaces based on the POSIX standard, and a common set of core system utilities, many of them originating in the GNU project that began in 1983. What really sets the distributions apart from each other from a user perspective is mostly:

A brief word on package managers for anyone unfamiliar with them: a package manager is a piece of software that installs, updates, and uninstalls software on the system, allowing the user to manage updates for everything from their image editor and web browser to the kernel itself from one place. Most Linux distributions have always had some kind of package manager, and there are several popular options, including the Debian project’s APT, Red Hat’s RPM, and Arch’s Pacman. A real centralized package manager like this is a relatively new concept in Microsoft Windows, but will be familiar to users of the Play Store or F-Droid on Android phones, or the App Store on iOS devices.

Package managers in desktop and server Linux distributions face an extra challenge that these popular mobile package managers don’t; Linux applications are frequently packaged and distributed separately from the libraries on which they depend. A library, in software, is a set of instructions for doing something that a lot of applications might need to do, like playing a sound file or displaying clickable buttons. The Linux kernel doesn’t contain instructions for playing sounds files or displaying clickable buttons; after all, a Linux web server doesn’t need to do those things. So the library allows an application to do these things in a consistent way on various machines without having to reinvent the metaphorical wheel. On Linux systems, these libraries are typically shared amongst different applications; one copy of a library can be used by a web browser, a media player, and an image editor. Doing things this way saves disk space and means that when when the library is upgraded, all the applications using it could benefit right away.

The problem with shared libraries is that updates to a library often require changes in the way that applications use them, and not every application is developed or maintained at the same place, so often package managers wind up in a situation where the latest versions of different applications require different versions of the same shared library. In the worst cases this can trap the user in a “dependency hell” where different applications cannot coexist because they require different versions of the shared libraries. Dependency hell has accelerated in recent years as the growth of Linux systems in corporate settings has driven rapid changes in common libraries to accommodate their security and “scalability” needs.

There are several approaches to preventing dependency hell. Systems like AppImage and Zero Install include copies of the libraries bundled up with the application itself so that the application has exactly the library versions it expects and doesn’t have to share. Increasingly popular options like Snap and Flatpak use a container approach that takes things a step further by also including various system files—pretty much a little chunk of the operating system, everything the application needs to run except the kernel itself. But all of these systems are meant to supplement, rather than replace, the systems primary package manager, to handle a few complex applications and not all the system software.

Nix is a relatively new package manager designed to solve the dependency hell problem with a more middle-of-the-road approach that can efficiently manage all system software while allowing multiple versions of shared libraries to coexist. While traditional system package managers keep applications all jumbled up together in the same few folders (for example, most of the programs themselves are in a folder called /bin/, while lots of shared libraries are all kept together in /usr/local/lib/), Nix instead keeps every individual package, whether it’s an application, a library, or a font, in its own folder identified by a cryptographic hash, a unique number mathematically derived from its contents, and uses symlinks (basically shortcuts between folders) to connect each package with the folders containing the exact dependency versions it was built to use. If the user upgrades a shared library but has an application that still requires the older version of it, the application simply remains connected to the older version, while applications that have been updated to take advantage of the upgraded library can use that, and each application is only aware of the presence of the exact version of the library it expects.

Packaging software for Nix is surprisingly easy compared to other software packaging approaches I’ve tried. It often requires the package maintainer to write just a single file, a “derivation” that typically describes how to download the source code for some software from the internet, compile it, and install the compiled files to the correct location. Nix derivations are written in the Nix programming language, a pure functional language designed just for defining software packages and system configurations. Like any pure functional language, Nix enforces a philosophy of reproducibility—that the same inputs (in this case, the same source files downloaded from the internet) should produce the same outputs (the same working, compiled piece of software) every time.

So one thing I love about NixOS is its package manager, the Nix package manager, and I’ve chosen to explain this first because (to refer back to my earlier list of three things that differentiate Linux distributions from each other) NixOS extends the same principles of reproducibility and efficient modularity to the default set of applications and the installation and system configuration experience.

When you prepare to download an install disk for NixOS, you don’t have the same array of options to choose from that you have with some other popular systems like Ubuntu or Fedora. With those distributions, you can choose from different Ubuntu “flavors” or Fedora “spins” with different sets of default packages included. Maybe you want one with an XFCE desktop that runs efficiently on older, slower graphics hardware, or maybe you want one that installs a bunch of multimedia creation tools by default, or maybe you want one designed for a server, that doesn’t come with any graphical tools at all. NixOS doesn’t come in “flavors” or “spins” like this, though of course you have a choice of install disks for different architectures, and you can choose between a smaller disk with just a basic set of command line tools and a larger one with a KDE desktop, Firefox browser, and the GParted graphical disk partition editor. You can still choose between different desktop environments and default applications, but you declare those choices during the installation process.

Here’s where I should note one big caveat about NixOS and the Nix package manager that will deter a lot of users: neither the NixOS installation process itself nor the Nix package manager has a graphical interface. Right now (as of August 2020) both are command-line-only tools, whereas the Ubuntu, Fedora, and Manjaro Linux distributions (for example) provide friendly graphical interfaces for these tasks. But the basic technical underpinnings of NixOS make its command-line installation experience very different from installing, say, Arch from the command line, or from the process I used to install Debian through a series of textual dialog boxes ca. 2005.

The part of the NixOS installation process where you’re most on your own is in partitioning your hard disk to allocate and format the space that will contain NixOS. This is something that I hope can eventually be smoothed out for beginners with a graphical tool that can automatically configure sensible defaults. As it currently stands, the NixOS Manual provides step-by-step instructions for this task that will probably be sufficient for users already familiar with the Bash command line in Linux environments, and the GParted disk partition editor provides a graphical interface for this step that will be self-explanatory to those who already understand how hard disks are usually partitioned to accommodate a Linux-based operating system. You can probably see how this limits the current audience for NixOS.

But we haven’t got to the good part yet. Next the NixOS manual provides command line instructions for mounting the freshly-partitioned disk (again, a technical step that could be automated away behind a friendly graphical installer) and a single command for generating a special configuration file called /etc/nixos/configuration.nix. This file is where the real magic happens.

Today’s software engineering field is keen on configuration as code. If you have an important server running somewhere, say in a virtual machine (a sort of simulated computer which could be one of several running on one actual, physical computer) and doing something that other people rely on (e.g. hosting videos online, or securely transmitting patient records between medical institutions), you need a way to recover this server in the event that it abruptly disappears. Natural disasters could happen wherever your server is physically located, newly discovered security flaws could require you to start over with a patched version of your server’s operating system, or someone could just mistakenly delete an important virtual machine; it happens all the time! When that disaster comes, or if demand suddenly increases and you need more copies of that server to keep up, you need to have a predefined set of steps for setting up a new server that works just like the old one. The more traditional old way of doing it is to write these steps as an instruction manual for a human operator: press this button, then choose that menu option, then run the commands… This method is prone to being misunderstood, or becoming obsolete because the tools that the human operator uses have been changed. Even when it works, it takes time. If you want to create a bunch of temporary servers all at once to handle a surge in demand (something businesses these days often do) having a human operator follow an instruction manual to create each one is not a viable approach. A more robust approach is configuration as code, where all those manual steps are somehow replaced with code that can be saved somewhere and describes the configuration of the whole system in a computer-readable way, usually something understood by a special tool like Puppet, Chef, or Ansible that can use that code to reproduce that configuration in one go, taking care of all the individual steps that would otherwise have to be done manually, and ensuring that things turn out the same way every time.

The NixOS configuration file is configuration as code built right into the operating system itself. Like Nix package derivations, it’s written in the Nix language. This is where really all of the basic system configuration is stored. Settings that, in other Linux distributions, are spread across a bunch of different system tools and components, like GRUB (which loads the operating system when the computer is powered on), systemd (which starts and controls system and background processes), the display manager (which provides a graphical login screen and opens the user’s desktop), and the user/group management utilities, can all be described right in /etc/nixos/configuration.nix. you can list all the applications you want installed by default here too—LibreOffice, VirtualBox with or without its Extension Pack, VSCodium, nginx, you name it. By default this file created with the right configuration to properly boot the operating system when you start your computer, and with comments showing the lines of code you would need to set up a few commonly desired features like printing, WiFi, and a graphical desktop (the KDE desktop). But all of this is optional, and online you can find examples for all kinds of different configurations you can mix and match to create something like the different “flavors” and “spins” of popular Linux distributions, fit to run anything from a small web server to an office-and-gaming desktop.

This level of customization isn’t new. Fifteen years ago I could achieve that through the seemingly endless dialog boxes of the Debian network installation. What is new is that it’s captured in this one file, which I can change at any time and even copy over to another machine if I ever have to replace the laptop I’m using. And once everything in the file is right all I have to do is run one command to tell NixOS to finish the system installation based on that file. If I’ve done something—if, say, I forgot a semicolon in the file where there should have been one—i just fix the file and run that command again; the NixOS installation command picks up where it left of and accommodates any changes I’ve made. Later, when I’m actually running the system I installed, if I want to change this configuration file again, I can apply the new changes—even something as drastic as replacing the whole desktop environment—with a single command. And if I don’t like the way it turned out, I can easily go back to an earlier version without even directly editing the file; old configurations are saved by default.

Maybe the magic of NixOS will be lost on most everyday computer users. I do a lot of hobbyist tinkering, and what I love about NixOS is that it makes that tinkering less tedious and fragile. I can have my weird, very specialized, very customized, exactly-right-for-me system on any new machine without having to put in all this time trying to get things to be the way they were before. And I can try new ways of using my Linux desktop without worrying about whether I’ll be able to get back to how it was before, if the new setup doesn’t work out. I like it so much that I’ve only been using ita couple weeks and already wrote this long article about it and submitted three Nix derivations to the NixOS community to update or add packages for some of my favorite niche programs.

There’s another factor that distinguishes Linux distributions from each other that I didn’t list before: community. This is why I hope NixOS will introduce graphical installation and package management tools that provide sensible defaults to smooth the learning experience for beginners, while still enabling the fully customizable configuration as code approach for tinkerers like me. Perhaps there could be a set of default configuration files for the beginner to choose from, like the flavors and spins of other distributions. Fostering beginner curiosity is key to creating free and open-source software communities that grow, adapt, and thrive.

One final note that didn’t fit in the rest of the article: the GNU project has created its own operating system inspired by NixOS, called Guix, which replaces the Nix language with a pre-existing GNU-created language called Guile and replaces the mainline Linux kernel with Linux-libre, a version with all proprietary device drivers removed. Much of what I have said about NixOS could apply equally well to Guix.


Tony's letter

Published 20 Jul 2020, last modified 19 Sep 2020

A screenshot from Earthbound: Jeff says, "That Tony has a heart of gold..."

I just finished playing EarthBound, the Super Nintendo role-playing game originally released as Mother 2 Japan in 1994, for the first time. I’m pretty late to the party, having already played its Game Boy Advance sequel Mother 3 during that awkward time around when I dropped out of college ca. 2012–2013. Both of these entries in the Mother series are very much unlike any other video game I’ve played. In their basic gameplay mechanics they don’t vary too far from the RPG formula popularized by the Final Fantasy series, but in their narrative and aesthetics they deal very subtly with an unusual set of themes—the perils of masculinity, magic and miracles in seemingly ordinary lives and places, and the violent closing of the commons that accompanies capitalist industrialization—all while maintaining a bright, zany, musical, mostly upbeat, always offbeat style that is more than the sum of its elements. All in all, these games are great fun, and full of surprises, and take a lot of risks that would be unthinkable in a big commercial video game production for the North American market today, though they have inspired some breakout indie successes like Undertale. Everything about them is what I love in video games and also exactly what the industry isn’t looking for right now. They’re RPGs in a market that is now thoroughly dominated by first-person shooters. They’re gloriously and self-consciously cartoonish where the North American video game market has long favored gritty, open-world realism. And they encourage casual play requiring comparatively little manual dexterity in a market that has come to be dominated by e-sports.

But what I want to focus on right now is a single non-playable character from EarthBound. His name is Tony, and he’s not onscreen for most of the game, but he’s super-important. The game’s main playable characters, whose names are all customizable but default to Ness, Paula, Jeff, and Poo, are four kids drawn together from different parts of the game to defeat the interplanetary invasion of a mysterious alien force called Giygas, which has begun to secretly inspire violence and greed among ordinary people and will eventually consume and destroy the world. Jeff is a boarding school student from a country called Winters, who has inherited an extraordinary gift for creating, fixing, and operating machines from his father, the famous inventor Dr. Andonuts. Tony is ostensibly Jeff’s roommate, but he’s also basically Jeff’s boyfriend.

When the player first takes control of Jeff he’s in bed at his boarding school, having just been telepathically contacted in his dreams by Ness and Paula, who need help elsewhere in the game. He shares the room with Tony, who appears to still be asleep in his own bed. If you have Jeff talk to him before leaving the room, he admits he’s just been dreaming about Jeff:

Ah, Jeff, I just dreamt that you and I were taking a walk.

…What’s wrong?

Whether or not you choose to make Jeff wake Tony on his way out of the room, Tony will see that Jeff is sneaking out, accept without explanation that Jeff has something important to do, and go out of his way to make sure that he can escape with any equipment he might need. This culminates with Tony giving Jeff a boost over the school’s gate—he lies down and you need to have Jeff step on him just to get out to the next area of the game.

Tony next appears about midway through the game, some time after Jeff has joined Ness and Paula in their adventure; the group receive a letter from Tony, imploring them to take good care of Jeff. And then Tony becomes the only character in the game (apart from the narrator) to address the character directly, breaking the fourth wall. He says he needs your name for a school project; this is how the game collects your name to use it later on. But he doesn’t appear on screen again until the player characters infiltrate an underground Giygas base, where Tony is among several unrelated characters who have been abducted and are held in what look like enormous beakers of water until you can liberate them. At first, Tony only addresses Jeff, although by this point the player controls a party of four characters; he had complete faith that Jeff would come to his rescue and eventually explains to the others that Jeff is his “best friend,” and that they “go way back.” But from that point forward the player characters have to continue their quest without Tony again.

Tony appears during the game’s final battle, as one of several characters Paula telepathically recruits to help the protagonists stop Giygas, and this is the last time he’s on screen apart from the end credits. But he gets a final word in after this last big battle. When Poo leaves the party and returns to his distant home country of Dalaam, he leaves behind three letters from the characters who miss Ness, Paula, and Jeff the most. Ness gets a letter from his mother, who has been waiting for him at home. Paula gets a letter from kids at the daycare center she helps her parents run. And Jeff gets this letter from Tony:

Dear Jeff,

Everything’s really going great here. I wish I could have gone with you on your adventure, even just part of the way, but instead I’m sitting here, waiting for you in Winters. I want to see you again as soon as possible. I can’t wait to see your cheerful face. I bet your glasses are dirty… If you come back, I’ll clean them for you!

Like I said, I’m waiting for you.

Yours truly,
Tony

P.S. Don’t show this letter to anyone!

At this point Jeff has left the party and is already preparing to go home to Winters… to see Tony, he says. If you have Ness read the letter before presenting it to Jeff, he says:

Ah, Ness, you’ve read it already…

…That Tony has a heart of gold…

So that’s it. That’s the whole story of Tony. He’s passionately devoted to Jeff throughout the game, does everything a non-player character can do to help him out, and in it’s own small way the game celebrates this as something special and important. It’s just one of many small interwoven stories that make up the narrative arcs of the Mother games, and it’s certainly not the most bizarre or head-turning. But it’s significant to me, and I wanted to say a few words about why. Mainly that’s because it’s still kinda rare to have male character in a piece of pop media care for another male character in this way without narrative going out of its way to pull a “no homo,” whether through jokes or through some variation on “Don’t worry, he has a girlfriend…” EarthBound does neither, and that’s especially surprising in

The game never specifically uses a word like gay or boyfriend in the context of Tony’s relationship with Jeff. And, as a player character, Jeff doesn’t have many opportunities in the game to demonstrate the degree to which he does or does not reciprocate Tony’s devotion. But you’d have to be pretty obstinate not to see something significant in Tony’s behavior toward him. In an interview partially translated by EarthBound Central, EarthBound writer-director Itoi Shigesato explains:

I designed him to be a gay child. In a normal, real-life society, there are gay children, and I have many gay friends as well. So I thought it would be nice to add one in the game, too.

I’m pretty cynical about the drive to seek improved media representation of minority groups, not because I don’t think it’s worthwhile, but because I’m sometimes concerned that people could get caught up on trying to achieve that when there might be more practical or more urgent opportunities for meaningful structural change, and because I feel that commercial media in a capitalist society is fundamentally limited in its ability to represent the human experience. But the fact is that, while I was drawn into various fictional worlds growing up, I really struggled to find characters that I really related to, as someone who didn’t have the words to describe any of this yet but was autistic and not straight. Being white, I did see a lot of fictional characters who superficially looked at me, but I could hardly ever relate to the way they moved through the world, as it were, without imagining experiences that were fundamentally different from mine.

So it’s a little thing that still gets to me, just to see male characters caring for each other in this way without it having to be a joke or something the narrative has to excuse in order to protect someone’s masculinity. I’m disproportionately excited when I see it, like someone who has walked just a little too long without water finally coming home to the kitchen tap.


Who let me buy a huge truck?

Published 19 Jul 2020, last modified 15 Sep 2020

A photograph of my truck

If you asked me a few years ago where I saw myself in July 2020, I would probably not have imagined that I’d be in the driver’s seat of a big, dually-rear-wheeled, diesel-fueled pickup truck. I find maglev trains and the proliferation of mass transit a lot more exciting on a personal level than having control of a personal vehicle with enormous horsepower.

But now I have this big old truck. Or we have this big old pickup truck. It’s mine on paper but it’s my spouse who plans to drive it most of the time. We decided a while ago that we wanted to try living in an RV for a while as a family, and at that point we indirectly committed ourselves to having a big truck like this: the RVs that can comfortably accommodate all of us who live together in this family are big “fifth-wheel” trailers and those trailers are designed to be towed by big pickup trucks. And they really have to be diesel trucks; gasoline starts to become a less efficient fuel when one is towing something this heavy, and as of right now (July 2020) there is no electric truck on the market with that towing capacity. So, soon after I started my first salaried, full-time, office job—remotely, of course, due to the pandemic—I signed some papers and somehow bought a truck, essentially the first one we found for sale nearby. It’s a 2011 model, and it doesn’t have all the luxury features like a moonroof, but it has the towing specifications we were looking for.

It’s a little scary; I have this feeling that I shouldn’t be allowed to buy something like this and the fact that I got it financed and the dealership just let me sign all these papers so we could drive the truck away was a mistake at some level. I mean, yes, my income and credit score have both gone up recently because of a few choices and a lot of plain old luck, so technically I’m a qualified buyer now in the eyes of the financial industry. And yes, we have specific plans that reply on this specific kind of vehicle. But the aesthetics of it are all wrong, aren’t they? Certainly I’m not the right kind of person to have this truck.

There’s an especially weird kind of commodity fetishism built up around vehicle ownership, and especially here in the United States, where mass transit never really recovered from the contraction that coincided with the explosive postwar growth of car-centric suburbs and the Eisenhower Interstate System, we tend to see the cars we drive or don’t drive less as machines created and assembled by people in Korea or wherever and more as concrete extensions of our personalities. If you met me you might guess that I drive a Prius. You’d be wrong.

For a good long while I couldn’t afford a car even with financing, so what I’d actually been driving to work before the pandemic made me a remote employee was my father’s old car, a 2010 Kia Forte, which is still in good enough condition that I plan to give it to a relative. That, in a way, tells a story about me. It tells you that I had enough privelege to receive this car from a relative so I could pursue jobs and educational opportunities that would have been out of reach for me without one, and also that I didn’t have the wealth at first to simply choose the sort of car I liked best.

But that’s not really the sort of story that we’re telling ourselves when we think of “Prius people” or “BMW people” or “Tesla people”. People have a bizarre need to not only make inferences about other people based on the cars they drive (or don’t drive), but also to shape their own driving habits according the various market niches that car manufacturing companies have devised. Driving a Tesla shows that you’re trendy and either rich or just enough financially solvent and devoted enough to a post-fossil-fuel world to have saved up a whole lot of money for one of these things. Driving a Prius shows that that you’re thrifty and eco-conscious. Driving an enormous Ford truck like the one I just bought shows you’re a rugged member of the National Rifle Association who doesn’t believe in anthropogenic climate change. None of this real, exactly, or maybe there are a lot of people who do happen to fit these stories, but they are market-driven stereotypes, mental shortcuts we make in an environment where we are alienated from each other and use the superficial signifiers of the make, model, even paint color of cars as a substitute for actually knowing anything about the people inside. Like any such shortcuts, they’re limited, and only work in the flight cultural contest. What kind of person would drive a GAZ 24 Volga in Moscow in 1988? Most people I know wouldn’t have any kind of intuitive judgement about that.

So, anyway, am I big truck person now? I don’t know, but I have a big truck…


2020 Commencement address

Published 24 Jun 2020, last modified 15 Sep 2020

I submitted the following with an application to participate in my university’s 2020 Commencement Exercises as a student speaker. I didn’t end up delivering the address as part of the ceremony, but I like how it turned out, so I wanted to keep it here on my blog.

The Merrimack River at dusk, viewed from University Avenue Bridge, Lowell, MA

I’m a computer science student born in 1991, so it might not surprise you that I have an enamel pin made to look like a Windows 95 dialog box. It says, “Task failed successfully,” and this is something of a personal motto for me.

Four years ago I was sitting in the Tsongas Center watching my younger brother receive his bachelor’s degree in Music Studies. I felt a mixture of pride—my brother is awesome, after all—and regret. I felt that I had closed the door on formal education in my own life when I dropped out of college in 2012.

I have a complete stranger to thank for giving me the push that finally convinced me to go back to school. I was working at a local wholesale store when someone came by looking for help choosing a camera in the electronics department. When I had told him all he wanted to know about cameras the conversation became a little more personal.

“You’re a smart guy,” he said. “Are you in school?”

“No, I haven’t been in school for a few years.”

“Why?”

“Well, I was in college for three years, and it didn’t work out.”

“Oh, are you going back?”

“I don’t know…”

“You’re a smart guy! You should be in school.”

What is this guy’s problem?, I thought. That’s none of his business! But it stuck with me. I couldn’t stop thinking about it. I was finally able to move on from ruminating on why I left school in the first place and focus on what I could do with a degree in computer science. What I could do for myself, for my family, and for my child. How I could harness my experience to get more out of school than I could have if I had finished my degree the first time.

And with a lot of help and patience from my family that’s what I did. I’m celebrating with all of you today, and I already have a job I could hardly have imagined when I was stocking shelves. Right now that seems a rare privilege, the kind of good fortune for which I can claim only part of the credit.

Sometimes my coworkers will say, “You learn fast. You could have learned everything you need to know for this job on your own, and your degree is just the proof.” And, you know, if they were just talking about the technical stuff, they’d be right. But the role of a school is more than dispensing technical knowledge. A school is a community, and when things go right a school helps you learn what there is to learn.

Communities are tested and shaped through shared adversity. Over the past semester I’ve seen faculty and students adapt to circumstances most of us never imagined. I don’t think any of my professors this semester had taught a class entirely online before. Some of us, myself included, had our children with us in the “classroom” for the first time. Times like these lay bare the challenges and the priorities we already had.

Education begins when we are united by a common demand. We are here because we want to know more and to do better. At UMass Lowell my professors demanded that I learn how to write microcode for the MIC-1 processor architecture, how Type Ia supernovæ can be used as standard candles for measuring intergalactic distances, and who wrote The Protestant Ethic and the Spirit of Capitalism. (It was Max Weber, by the way.) None of this is knowledge I will ever be asked to use at work. But it is knowledge I cherish because it tells me something about how we got here, why we do things the way we do. And knowing how we got here gives us a starting point from which to move forward.

I’ll leave you with another of my personal mottos, one that was found anonymously scrawled on walls throughout Paris in May 1968: Soyez réalistes, demandez l’impossible—Be realistic, demand the impossible. Demand it of your communities. Demand it of yourselves.


City on hiatus

Published 19 Jun 2020, last modified 15 Sep 2020

Upper Great Highway in San Francisco, temporarily closed to vehicle traffic to encouraged socially distanced exercise

I believe San Francisco officially began to allow outdoor dining at restaurants during our last full day in the city; I didn’t actually see any restaurants doing it while we were there. Reopening of “non-essential” retail to walk-in customers wouldn’t happen until we had left. Though there were some nights we heard some faint noise from the streets, some distant drumbeats or even the eventual firecracker, by the time we left the 8pm curfew had been lifted and the nights were mostly quiet in Outer Sunset. Sometimes during my walks I would anxiously side-step a small crowd of people waiting to take out food from a restaurant or bar—all the more anxiously if they were loitering mere inches apart across the width of the sidewalk with no masks, or with their masks dangling uselessly below the chin. But the doors at Safeway were patrolled at all times by store employees or even police, refusing entry to anyone who didn’t have their mouth & nose covered. At one Safeway store I visited on Noriega in Sunset I even saw a patron in a full face shield in addition to the mask.

While I had expected to spend much of my downtime during the trip reading novels or writing letters, I spent more of it on little technical projects—like creating this blog itself, which is a very simple Django app I wrote from scratch—or on walks about town. I didn’t hit a lot of city landmarks; mostly I just saw what I could get to by walking. One especially long and meandering walk eventually took me along El Camino del Mar and Sea Cliff, through a neighborhood of otherworldly mansions where I felt entirely alien, and to the edge of the Presidio, which fascinated me though by that time I’d clearly gone too far and had to get back to my sister.

A trend I noticed throughout our stay was hand-drawn or hand-painted rainbows displayed in the windows of many homes across the city. At first I saw a number of them accompanied by some message like “Thank you, healthcare workers” but increasingly throughout my stay the message beside them was “Black lives matter.” It was heartening to see public sympathy to this movement awoken so widely.

For me, the charm of the place never wore off for the two weeks I spent there, but over time certain realities I knew about it came into sharper focus: that this was a city on hiatus, that while new cases of COVID-19 reported daily were falling in my home state they were rising in the Bay Area, that institutional racism was at least as alive there as it was at home, and that this was not a city I or most of my friends & family could realistically afford to live in. There were moments when I was tempted to wonder why anyone wouldn’t want to live in San Francisco, but there were two really obvious reasons that always came to mind immediately: money & racism.

Months before I came to San Francisco I read Lauren Smiley’s long-form article in The Atlantic, “The Porch Pirate of Potrero Hill Can’t Believe It Came To This.” Its subject, San Francisco-born Ganave Fairley, has a personal history with faint echos of Jean Valjean at the outset of Les Misérables. Accused of a string of petty thefts in which packages were stolen from the doorsteps of her neighbors in Potrero Hill, her life was completely upended and her family torn apart by the criminal system; she lost her home and her daughter and eventually went to prison.I often think of this, but thought of it in San Francisco especially, how what seems to be a generous community of kind neighbors can wield such disproportionate violence when someone’s delivery of assorted hot sauces goes missing. And, truthfully, it’s hard to imagine a white woman in these United States today facing some of the comments and legal actions leveled against Fairley.

Still, I do hope to visit the city again, sometime when COVID-19 cases are no longer on the rise, sometime when the Japanese Tea Garden is open and I wouldn’t feel irresponsible riding a crowded bus to see it.

The last meal I ate before leaving the city was a ridiculously decadent fast food feast I could never get at home: spam musubi, curly fries, a Nutella-flavored mochi waffle, and a “Hokkaido caramel” milk tea with boba, all from Quickly in Sunset. II kept thinking about it for days afterward.

The journey back home was even stranger than the flight out west, not because things were further from pre-pandemic norms but precisely because they were a little bit closer. Our nonstop flight had been cancelled and we’d been left with a four-hour layout in Seattle, in an airport I knew from a pre-9/11 period of my childhood when one could go all the way to the gates without a boarding pass, to meet an arriving passenger or just to watch takeoffs and landings. It seemed busy as ever, with not nearly enough seats for us to stay six feet apart from other passengers waiting at the gate, and most of the airport shops were open. Nearly everyone was masked but I overheard other passengers complaining about it in cell phone conversations. I bought a few cheesy postcards from Hudson News, postcards with views of Seattle that I probably could have purchased in 2003 when I last lived in the area, and some food to sneak onto our next meal-service-less six hour flight. On the plane I listened to a “cosmic country” playlist, the voices of singers like John Prine and Yola lulling me halfway to sleep as the sun rapidly disappeared behind us.