True, depending on your language, you can probably get the imperative version to be shorter than my pseudo-C implementation.
But that accumulating function you're passing to reduce? That's essentially just a JavaScript version of the bind (>>=) operator for Maybe. In fact, in Haskell, I'd express what you wrote as:
foldl (>>=) x [foo, bar, baz, quux]
foldl is Haskell's version of reduce, so that's almost exactly the same as your code. You're using a monad to shorten your code, you're just not being obvious about it!
If you take this pattern and generalize it to having arbitrary behavior between each function call, you basically have monads where the [foo,bar,baz,quux] bit sort of acts like do notation in Haskell. The exact details might not be entirely the same, but it is exactly the same idea: you can control how a bunch of functions get composed.
So you'd have code that looks just like yours, but depending on which "monad instance" you parametrize it with, it could have different behavior. So you could uniformly represent code that could return null, code that could have multiple results or even parser code. And, very importantly, you could write other functions that act over all these different behaviors. So you could implement a reduceM function that would support a reducer that could return null, or one that could return many elements, or plenty of other possible behaviors in a uniform way.