Hover compiles one source file into two clocks: a discrete task for the MCU and a continuous solver for the plant it drives. A crossing without sample or hold is a compile error, not a warning.
module motor_loop {
plant motor {
state omega: rad/s = 0.0
integrate omega' = (kt * i - b * omega) / j
}
controller foc on every 50us {
let e = target - sample omega
emit pwm = hold pid(e)
}
}
Every controller runs on every a stated period. No hidden scheduler, no implicit polling — the timing in the source is the timing on the target.
A plant block declares state and its derivative with integrate. The solver steps it between samples; you never hand-roll an integrator.
Reading continuous state into discrete code needs sample; writing discrete output into the plant needs hold. The compiler rejects the crossing without them.
Hover keeps the discrete task and the continuous plant in two explicit domains, joined at one checked boundary — the same seam the palette marks in yellow, blue and red.
Controllers, state machines and I/O run on the sample clock you declare. Deterministic, timed, compiled to your target.
Motors, circuits and mechanisms evolve as differential state, stepped by the solver between samples.
Install the compiler, run the DC motor example, and watch the trace channels agree at every sample point.