It’s near my bedtime, so treat this post with caution, but I think I see the logic of that construct clearly so here goes.
Macros are implicit group wrappers in their own right, so the
choose block in your second example is rendering a bare term with no attempt to render a variable. That’s confirmed output, which the group returns to the parent (the
group wrapper in the second example). The
foo attempt fails, but the “no date” term is not dependent on it (because it’s already confirmed).
From a style author’s viewpoint, treating macros as implicit groups is friendly, because everything you need to think about is in the code block in front of you—macro calls render or they don’t, and variables will pull down the companion terms that you can see in the block if they all fail.
(Having written that, I sense a question over what happens if a macro returns with a lone string or term, but to a group with a failing variable and a sibling term—what happens with the sibling term? I’m pretty sure that the macro return is treated as equivalent to a succeeding variable, and that you would get the sibling term in output.
I’m at risk of not making sense, so I should wait until tomorrow to dig into it, but in
citeproc-js there is a set of named parameters for tracking group state that will be helpful in clarifying the logic, and maybe useful as an example.