I am attempting to implement a function that returns a recursive closure., though I am not sure how to express that in the function signature. Here is example code of a working implementation in Python
def counter(state):
def handler(msg):
if msg == 'inc':
print state
return counter(state + 1)
if msg == 'dec':
print state
return counter(state - 1)
return handler
c = counter(1)
for x in range(1000000):
c = c('inc')
and pseudo code for Rust.
enum Msg {
Inc,
Dec
}
fn counter(state: Int) -> ? {
move |msg| match msg {
Msg::Inc => counter(state + 1),
Msg::Dec => counter(state - 1),
}
}
A recursive termination is a condition that, when met, will cause the recursive function to stop calling itself. Because of the termination condition, countDown(1) does not call countDown(0) -- instead, the “if statement” does not execute, so it prints “pop 1” and then terminates.
All functions - recursive or not - have one or more return . The return may or may not include a value. It is for you to decide when you write the function. All explicit written return statements must return the correct type.
Aside from that, if you've called your recursive function a given number of times, returning from the function would return you to the previous call of that function. A return statement won't stop all the prior recursive calls made from executing.
Because Rust supports recursive types, you just need to encode the recursion in a separate structure:
enum Msg {
Inc,
Dec,
}
// in this particular example Fn(Msg) -> F should work as well
struct F(Box<FnMut(Msg) -> F>);
fn counter(state: i32) -> F {
F(Box::new(move |msg| match msg {
Msg::Inc => {
println!("{}", state);
counter(state + 1)
}
Msg::Dec => {
println!("{}", state);
counter(state - 1)
}
}))
}
fn main() {
let mut c = counter(1);
for _ in 0..1000 {
c = c.0(Msg::Inc);
}
}
We cannot do away with boxing here, unfortunately - since unboxed closures have unnameable types, we need to box them into a trait object to be able to name them inside the structure declaration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With