Consider product as a counter-example. With an imperative loop, it's easy to add an early-out condition if
zero is encountered. But this is harder to do in a (strict) functional language.
This is exactly why lazy evaluation is often described as control-flow. Lazy evaluation permits efficient composition, without doing extra work (although the constant factors become much larger).