May 15, 2025

Import Soultion

If you want to make an apple pie from scratch, you must first create the universe.

The other day, I suddenly felt the urge to learn about how email works. Or an email client, at least. Building a simple prototype seemed like a potentially fun weekend project. As I understand it now, it's not too different from the rest of the internet. You send a request to a server that conforms to some protocol, you get a response back with your messages.

I'm only considering POP3 here, since that seems easiest to implement. You can read the whole POP3 spec here, but I've never been able to get my head around an RFC. Initially, I thought I'd be opening a socket, then creating and sending some requests. I went looking around to see if I could find some example to work from. Instead, I learned that python's standard library includes poplib, a POP3 client already there waiting for me. At the end of that doc page, there's a simple example:

import getpass, poplib

M = poplib.POP3('localhost')
M.user(getpass.getuser())
M.pass_(getpass.getpass())
numMessages = len(M.list()[1])
for i in range(numMessages):
    for j in M.retr(i+1)[1]:
        print(j)

And we're done. Hooray. Ok, so import solution isn't that satisfying. The real work of building an email client is all the other stuff, like building an interface, storing and retrieving messages, and such. But creating a usable, polished application was never my goal. So this isn't a post, as much as a story to explain why I didn't write a post. Maybe some reflection on the sorts of things I find interesting and the things that seem tedious. There's some tension between my desire to understand things at a lower, fundamental level, and my desire to just make something that works.

I could go through and implement my own version of poplib. The source code is less than 500 lines long, after all. But just re-implemting something line for line doesn't do it for me. And I'd end up relying on a built-in SSL library. It's dependencies all the way down. Eventually, I will be annoyed at myself for not manually transcribing machine code into punch cards, or not 3D printing my own paper tape reader. At what point do we just give up and accept the black box that makes the thing work?