Search code examples
rustfunctional-programming

How can I re-write this loop as a closure?


let mut result = some_func();
for s in some_iterator {
    if result.is_ok() {
        break;
    }
    thread::sleep(time::Duration::from_millis(10));
    result = some_func();
}
// use result

I have a code that looks like above, retrying to call some_func(). Here, I have to declare result as mut to update it during the retry. Is there some functional magic that I can use so that I do not have to declare result as mut?

I thought about the following, but do not think it is an ideal example, since I will have to iterate over each element of some_iterator there, which is not what I want

let result = some_iterator.fold(some_func(), |result, x| {
    if result.is_ok() {
        return result; 
    }
    // sleep and retry 
});

Solution

  • Don't. It's much harder to adapt such code to changing requirements, like "add an overall timeout", "add a maximum retry count", "abort on non-retryable errors", or "do exponential backoff".

    Instead, create a proper RetryStrategy abstraction that you just give the "fetch" closure and maybe a "is error fatal" closure. Better, use one that already exists, like maybe the retry or backoff crate.