Lab note #064 Current API and developer affordance with more scheduler work

The work on the scheduler is to support async effect handlers. It won't do at all, if a network request always blocks the evaluation of the computational graph. So I embarked on it about two weeks ago.
Right now, the API looks like this (subject to change). There's a class to track all the originating state.
class MyState:
@track
def a(self):
return 2
@track
def b(self):
return 3
Then we can use that state either directly, or with functions that use that state (derived state).
@reactive
def triple(self, state):
return 3 * state.b + 3 * state.c
@reactive
def square_triple(self, state):
return self.triple(state) ** 2
Reactive functions can raise effects by yielding a description of the effect. And we handle the effects with a handler.
@reactive
def log_state(self, state) -> EffectfulGen[Log, int]:
res = 3 * state.a
yield Log(f"multiplier result: {res}")
return res
with use_handler(MemoryLogging()):
self.log_state(my_state)
Effect descriptions and their handlers are mostly predefined, but if you need to write your own, you define an Ability (like an interface), and then a handler that implements the Ability. This is a little verbose for my liking, but it's good enough for now. I'd been tweaking the type checking on this for a while already.
@dataclass
class Log(effects.Effect):
message: str
class Ability(effects.Ability):
@abstractmethod
def log(self, effect: Log) -> None: ...
class PrintLogging(Handler, Ability):
def log(self, effect: Log) -> None:
print(effect.message)
I've tried to keep the API tight and easy to read, without a lot of boilerplate or fanfare. I mostly like it. However, with async handlers, I hope I don't have to complicate it too much. The core issue is how to represent eventual values. We have promises (coroutines in python), but they're not cancel-able and doesn't support multiple resumption. I'm gearing towards supporting both, which is why all this work going about a use-land scheduler.
At the end of the day, I think the solution Claude and I fell into was having a placeholder object as a proxy to the value. I'm not thrilled about it since the designers of React eschewed wrapping every reactive value inside a container so that users can do regular operations with them. In order to support that on my end, I'll have to override all built-ins. I hope I don't come to regret this choice, but the alternative is to litter awaits
everywhere.
Been getting used to mixing vibe coding into my workflow. I'm still learning exactly where Claude Code is better and where it's worse. The bones of the scheduler that it wrote is still there. However, I've had to rip out a bunch of stuff because on close examination the code it generates is rather confusing. It still need to be simplified further, but after this foray into vibe coding, I think I'll have to do it more manually. There are certain subsections I can ask it to code up, but not the core call chain and scheduling mechanisms.
I feel like I'm taking a lot of time with the scheduler, but I guess it can't be helped. My desire to understand how every part of this core works is because I'm afraid I'll have to debug it later on. It won't do to rely on AI to do it, since there are plenty of times where it just gets lost debugging. Every time I've blindly relied on AI, I've come to regret it. I'll grind away the rest of the week on this, and see where I'm at by the end of the week and re-evaluate.
I recently found Thorsten Ball's newsletter, Register Spill, in which he has a Joy and Curiosity section where he posts things that he's found. I think I'll add that to my lab notes every week as well, to add value to those of you that keep reading.
- Implicit Surfaces & Independent Research by Matt Keeter is one of the better talks I've seen this year so far. He starts with a simple premise: are we inside or outside of a shape? And then it crescendos into a compiler! This has ideas and implications for people working on spreadsheets and front-end frameworks, I think.
- Eric Meijer wants to encourage people to see the possibilities for probabilistic frameworks and differential programming languages in Alchemy For the Modern Computer Scientist. But I didn't even get to all that. I was introduced to dual numbers for the first time. It's exciting because it's a way to compute the derivative along with the function in the same "number." DbSP takes a similar approach. How are they related? Once I finish with the scheduler, I'll look into this.
- Claude Code was released and some people are poking about it to see how it works.
- The Socials are alight with MCP: "Model Context Protocol". I haven't looked into heavily yet, but there seems to be quite a bit of adoption already. It's a protocol for LLMs to talk and use various tools in a standardized way.
- Patrick's Parabox is a puzzle game that uses recursive mechanics. In most visual programming, the spatial dimension is flat. I'd want to see how to address composition, or functions within functions. Patrick might have some inspiration for people that way.

- Orion Reed's prototype on zoomable hypertext has got the Patrick vibes.
What if hypertext were zoomable? Then you could zoom forever, in circles... I made this zoomable wiki prototype the other day to figure out how to manage coordinate transforms in such a weirdly shaped infinite space https://t.co/oOOLKr84x0 pic.twitter.com/494SrENSMP
— Orion Reed (@OrionReedOne) March 11, 2025
- What's the right approach to new products? Pick three key attributes or features, get those things very, very right, and then forget about everything else. When it comes to products, Paul Buchheit's advice always sounds inane, but is always on point. It's a good reminder.