← Back to context

Comment by newzino

1 day ago

For hard real-time systems, the bottleneck isn't raw speed but determinism. You need guaranteed worst-case execution time (WCET), and GC pauses, syscalls, and dynamic allocation all make that impossible to analyze. Stripping all three out at the language level is the right call.

The copy-and-patch technique is the same approach CPython 3.13 adopted for its new JIT tier. You precompile a library of code "stencils" (one per operation), then generate native code by copying stencils into a buffer and patching in the correct memory addresses. No LLVM, no compiler infrastructure at runtime.

How does the tracing approach handle control flow in practice? The README says conditions must be known at compile time, with cp.iif() as a branchless workaround. For robotics control loops that's probably fine since the structure is usually fixed. A PID controller is all arithmetic. But a state machine with variable-length trajectories would be harder to express this way.

The autograd via cp.grad() is clever for the robotics angle. Inverse kinematics through gradient descent means you can handle arbitrary linkage geometries without deriving closed-form solutions by hand.

In some fields its quite common to implement state machines in an imperative style with if-blocks and flags. That should be possible with Copapy by having decorated functions where the decorator parses the AST and replaces if-blocks with cp.iif() to end up with branchless code.

However, from my experience this programming style is ok for simple state machines, but it’s definitely not great, and if things get more complex, it’s getting really hard to keep it comprehensible and correct.

I think the main challenge is the design of an API that fits state machines. Concerning the WCET, branchless code should be on average not worse than branched code.