Clueless about non-blocking loops

The page for imp.sleep() gives this example:

`
pin <- hardware.pin1;
pin.configure(DIGITAL_OUT);

function pulse() {
// Send a 50ms pulse out on the pin

// Set pin high
pin.write(1);

// Wait 50 ms
imp.sleep(0.05);

// Set pin low again
pin.write(0);

// Repeat in 50ms' time without blocking
imp.wakeup(0.05, pulse);

}

pulse();
`

The function calls itself endlessly. My small mind imagines that each of these calls causes a return address to be pushed onto a stack, and that stack grows without bound, until memory is full. Where am I going off the track?

imp.wakeup doesn’t execute pulse immediately. It queues it to execute again in 0.05s. Before that happens, the current pulse function will terminate normally and disappear off the stack. If the code had been written like so:
`
pin <- hardware.pin1;
pin.configure(DIGITAL_OUT);

function pulse() {
// Send a 50ms pulse out on the pin

// Set pin high
pin.write(1);

// Wait 50 ms
imp.sleep(0.05);

// Set pin low again
pin.write(0);

// Repeat in 50ms' time WITH blocking
imp.sleep(0.05);
pulse();

}

pulse();
`

…then you would get the same output, but no other squirrel would run. Squirrel detects tail recursion (ie calling the same routine at the end of the routine) and automatically flattens the stack, thus preventing a stack overflow. However, it does introduce blocking, which imp.wakeup neatly gets around.

If you wanted to avoid all blocking, you could replace the first imp.sleep with an imp.wakeup too:

`
pin <- hardware.pin1;
pin.configure(DIGITAL_OUT);

function pulseOn() {
// Set pin high
pin.write(1);

// Wait 50 ms then switch off
imp.wakeup(0.05,pulseOff);

}

function pulseOff() {
// Set pin low
pin.write(0);

// Wait 50 ms then switch on again
imp.wakeup(0.05,pulseOn);

}

// Send a 50ms pulse out on the pin
pulseOn();
`