Working Notes: a commonplace notebook for recording & exploring ideas.
Home. Site Map. Subscribe. More at expLog. Kunal

2026-04-5

Tempus fugit

Sending to Python Generators

A pattern I'd originally only used as a lark in Advent of Code several years ago is something I find myself returning too frequently recently: using generators, and even async generators as state machines that react to input.

Basically wherever I find myself writing an infinite loop that does work and waits for input; or if I'm manually driving an event loop (sometimes it's as simple as explicitly controlling time with ticks) this applies too.

A common pattern is calling LLM apis with a collection of messages; I'll use a remarkably simple api that's just a list of conversation messages. Then,

async def chat():
    client = LLMClient()
    response = None
    msgs = []
    while True:
        user_msg = yield response
        msgs.append("user: " + user_msg)
        response = client.send(msgs)
        msgs.append("model: " + response)

which encapsulates state for the api -- particularly maintaining state for the client, quietly maintaining the list of messages in a single generator I can easily walk over.

Making a conversation repl is fairly direct:

chat_gen = chat()
next(chat_gen)  # slightly clunky, but this gets us to the first `yield`

while True:
    user_msg = input()
    response = await chat_gen.asend(user_msg)
    print(response)

With all the details of the api neatly captured inside the generator object.

The equivalent without asyncio would just be generator.send; while I initially found these slightly confusing I think this is my favorite new way to write state machines.

Writing about Python

As I continue filling out the essay on How I write Python I'm realizing I desperately need to add examples to make all the principles concrete. I suspect that will make this much slower, but potentially worth the effort involved, tentatively with a simple open source project I've been thinking of for some time.

I'm also noodling with the idea of also publishing a .md file with a stripped version of the essay that can easily be fed to Claude & Codex -- I can use this for my day job to get code that feels like it's been written by me -- and also maybe influence and review a lot of other people's code to match my taste.

Ego

Cleaned up the existing code this week; writing against the OpenAI responses API is powerful but hard to reason about, which makse me more excited to get ego completed and extensible with hooks and an emacs-like system.

So far I've been resisting the siren call of generating the code with Claude just to be able to carefully reason about the design and extensibility and really mold/internalize how this works: I'm already using generators which I suspect would be out of distribution.

Books

Went back to several half finished books this week; particularly AI Systems Performance Engineering; and picked up several books on kubernetes, prometheus, otel and other more standardized ways of doing things. Prometheus is like fb303, though I often find myself trying to quickly have a CLI do the equivalent of top for a specific server while debugging. Maybe I haven't googled enough just yet, but I'll probably end up writing one.

(I was curious if there was cross pollination between fb303 and prometheus, but Claude says there wasn't: though I wouldn't be surprised if borgmon influenced fb303 a little bit. Conversation).

Developer Tools

I particularly enjoyed https://www.dbreunig.com/2026/03/26/winchester-mystery-house.html around the new era of developer tools that are built for a very person and will almost certainly only make sense for them.

Developer tools should look very different in this future, particularly for software engineers: I can spin up any tool I want fairly rapidly. This changes the kind of work that is higher leverage for people actually building tools

Even though I'm no longer required to make one 'meta' comment every day, meta-tool creation seems much more important and valuable now.

My notes on Building Developer Tools definitely need an update: particularly to account for build, buy, or run open source; and then to account for leveraging and working with AI. Someday.