John Meinel <j...@arbash-meinel.com> writes:

> The one things I'll specifically note about your "simple" example is
> that it doesn't actually handle errors. The fact that the "quick way
> to write it" is actually wrong is the specific argument of this
> thread.

Thanks for raising that point. I agree that coercing the developer into doing 
the right thing is an important point to consider when discussing these two 
approaches. I reject the fact that failed to do so in email as a straw-man 
argument as to how often this will occur.

> In your loop you have a way to generate a FinalResult, but no handling of the 
> actual "I couldn't
> get a result". The way above that you can tell the loop failed would be to 
> check if FinalResult
> doesn't have a valid value.

If I were truly writing this code in production, it would actually look more 
like this:

func foo() {
    /*...*/
    result, err := maybeSomeFunc(spec)
    if err != nil {
       return errors.Trace(err)
    }
    /*...*/
}


func maybeSomeFunc(spec retry.Spec) (interface{}, error) {
    var finalErr error
    for loop := retry.Loop(spec); loop.Next(); {
        result, err := SomeFunc(blah)
        if err != nil || resultNotGoodEnough(result) {
            finalErr = err
            continue
        }

        return result, nil
    }

    return nil, finalErr
}

And this doesn't take into account preemption, or the minutia of the 
domain-specific problem -- I might even write it differently depending on what 
I'm retrying. I.e. it's really hard to write a representative example. And 
that's kind of the point, right? We want to value composability for this very 
reason.

-- 
Katherine

-- 
Juju-dev mailing list
Juju-dev@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju-dev

Reply via email to