Rewriting Kopi again (well, cut and paste with tweaks)

2 views
Skip to first unread message

Mike Austin

unread,
Apr 2, 2026, 4:16:41 PM (2 days ago) Apr 2
to PiLuD
Starting over again helps focus on core functionality. Dynamic polymorphism with external methods (no monkey-patching). Long ago I used "_extensions" in the current scope, but by using Symbols I can hide all the methods and not worry about variable name clashing.

let env: Env = {
  a: new KopiNumber(5),
  [KopiNumber.symbol]: KopiNumber.methods
};

async evaluate(env: Env): Promise<KopiValue> {
  ...
  const method = env[leftValue.constructor.symbol)]
  method.apply(undefined, [leftValue, rightValue])
}

This makes it easy to add or inject methods (limited type-classes) to any type. Sorry, no static typing in this version either. I'm focusing on semantics, but hopefully could be added.

Mike Austin

unread,
Apr 3, 2026, 7:21:49 PM (23 hours ago) Apr 3
to PiLuD
Interesting thing about async or lazy code:

x = sleep 5
y = timeConsumingFunction 5

If I don't make statements / assignment synchronous, sleep, well, won't sleep until x is accessed.

(x, y) = (sleep 5, timeConsumingFunction ())

This turns it into a concurrent operation. The tuple is awaited, but the tuple elements are not, which means it won't sleep.

Hmm. I didn't want to get into blocking / non-blocking logic but that's what await / no await is. The only reason to block is for effects (time). Maybe there's a simple solution just for sleep.
Reply all
Reply to author
Forward
0 new messages