I've been doing tech stuff since I was in college, when I found out I could get paid to be a Python programmer. I had a professional position as a web programmer for several years at the University of Chicago, where I did a lot of Ruby (on Rails), a lot of Javascript and interface design, and a fair amount of PHP/Drupal work. I've gotten especially interested in the craft and design of software -- not just what the user sees, but the process of building it, the design patterns and the internal architecture. Anyway, here are a few thoughts on tech.

Contents

My life in code

I want to write something about how I came to programming, because not everybody has two careers running in parallel. If you just want to read my resume, go ahead and read my resume! But this is the story behind my resume.

I took some computer science classes back in high school and early college — mainly C style languages with object oriented features thrown in, as used to be the rage in the 1990s. I must have done a year of C++, with a semester of Java thrown in. I was a pretty classic late-90s nerd, I guess — even before I knew much formally about programming, I was playing around with writing GUI applications in C for my old Mac OS system.

I started to work for a language laboratory in college, at Cornell's Language Resource Center, and I ended up learning most of what I know about software/web development in the workplace. First I got thrown headfirst into Linux server land (originally Red Hat). I got up to speed in Python, which powered our now-totally-obsolete Zope platform. Before long before we needed non-document-based data storage, so I set up a MySQL instance, made it talk to Python, and learned something about normalized database schemas.

A few years later in grad school, I went back to web programming at the University of Chicago, in Humanities Computing. At first I worked on their public-facing websites (mainly Drupal); I remember building some custom event planning module for their big development event. Next door, there was a web applications programmer who was building internal administrative software in Ruby on Rails, which sounded more exciting. He gave me a crash course in Ruby, in the MVC pattern, and in test-driven development. Then he left for a startup, and I got hired into his position.

My code quality improved from more intensive practice (I think). But the real skill I learned through Rails development was about managing the larger lifecycle of a software project in a big institution. I shipped a lot of new projects and got better at supporting web applications in production. I got good at making clean, performant GUIs for our internal apps. (Unfortunately, they are all private — such is the nature of writing administrative software). I built our testing infrastructure up from almost nothing (lots of unit tests, some integration tests). I built a dashboard app to monitor realtime activity from end users. I got a lot of practice triaging production exceptions (which ones are urgent? which ones can wait a little bit? do we need extra logging or debugging?). I maintained our web infrastructure (not the Linux servers themselves, but the web and database software that ran on them). And I spent quite a bit of time working with our clients, who were mainly internal administrative offices who needed custom software.

It was also kind of wild to see how fast the web software scene was evolving. In academia, things move really slowly. The tech world was much more energetic, and everything seemed to change overnight. Javascript was becoming a more serious programming language, with build tools, better syntax (ES6), and better libraries. But mentally, the big shift for me was towards the more functional and dynamic styles of programming that were popular in Javascript and Ruby. I'd seen some of these styles in Python, like the heavy use of map and lambda functions instead of loops. But suddenly I found myself doing function chaining and passing around closures everywhere, thinking about prototypal inheritance (in Javascript), or writing Ruby DSLs in a more declarative style. I'd still like to learn more about fancier functional languages, and more about asynchronous programming, of the kind you need for client-side Javascript interface design.

Meanwhile, it turned out to be really useful to be trained as an anthropologist while working in software. It teaches you to really listen to people — clients and colleagues alike. It teaches you to write, in lots of different styles. And it helps you get good at moving between very different contexts and different levels of abstraction. That's what cultural anthropologists do — translate between contexts and idioms — and in a funny way, that's what you have to do in software development too.

So anyways, that's my little journey through software development. I've toyed with the idea of going back to get an MA in computer science — I know how to get a lot of things done with software, but sometimes I wish I knew more about compilers, discrete math, and some other parts of the computer science curriculum. We'll see!

How does this website work?

This website is based on hand-written static HTML. There's never been a strong enough reason to rewrite it in a dynamic web framework, or even to use a static site generator; the site is small enough that manual content editing is not annoying.

That being said, sometimes I do get tempted to start automating the editing process. I've written a few ruby scripts to update the site nav, and to pull in content from external data sources. If things keep getting more complicated, I just might have to stop reinventing features that I would get for free in a more full-fledged web development environment. Still, it keeps me in touch with the web to maintain a static site myself, to do the layout myself (even if it's not fancy), to maintain the CSS, to keep it minimally mobile friendly, and so on. Modern web applications have so many layers of abstraction, and it starts to be nice to simplify.

To give you a couple examples of things I've automated for this site, the HTML for my academic CV is autogenerated from structured data files. And if you look at the page about my current book project, the manuscript work log is based on the git log for the project.

Here's the script I wrote to transform a git log into HTML.

#!/usr/bin/env ruby

# argv0 should be the path to the git repo whose log you want to export
# invoke with `./update-writing-progress.rb "/path/to/your-git-project"`

require 'nokogiri'

OUTPUT_PATH = 'html/book.html'
OUTPUT_HTML_SELECTOR = '#writing-status'

# Find repo
abort("No repo path specified") unless ARGV[0]
repo_path = ARGV[0]
abort("Repo path not valid") unless Dir.exist? repo_path

# Load new content
raw_history = `git -C #{repo_path} log --pretty="%ad|%s" --date=short`
git_history = raw_history.split("\n").map { |line| line.split "|" }

# Render tabular content
new_content = git_history.map do |date, log|
  <<~HEREDOC
  <tr>
    <td class="info">
      #{date}
    </td>
    <td>
      #{log}
    </td>
  </tr>
  HEREDOC
end

# Parse output file and update
output_file = File.read OUTPUT_PATH
doc = Nokogiri::HTML output_file

output_html = doc.at_css(OUTPUT_HTML_SELECTOR)
abort("Output HTML entity was not found") unless output_html

# update with new content
puts "Updating git status content..."
output_html.inner_html = new_content.join("\n")

# show output
puts git_history.take(5).map &:last

# save
File.write OUTPUT_PATH, doc.to_html

I like writing these little shell scripts in Ruby -- I especially like the heredoc string interpolation, the handy library for working with HTML (nokogiri), and the low-overhead integration with other shell tools (backtick operators). Obviously there's more you would do to improve this script if it were for general use or public distribution -- more error checking, maybe a different strategy for doing configuration. But this is just a script I use privately, so it's safe to make some assumptions about the user. By the way, I'm sure there's a way of rewriting this script in one line of Bash, but I'll take readability any day.

I've also learned to love deploying web projects from git, so this static site lives in a private git repository and has a handy one-stop deployment script. It's served from nginx on Ubuntu.

Anyway, underneath this very simple static site is a larger thought that you learn from software development: all software constantly has to make tradeoffs given its environment and available resources. So partly, this project works as my sandbox for exploring some of the tradeoffs of modern web development. I could make a much fancier image gallery. But the old one works (on the devices I've tested) and I don't have a strong reason to improve it. Enough said.