The historical rule is that nothing vaporizes by default in REDUCE. If you have N expressions in, you will have N values out. There is a religiosity about it in Red.
If you think reduce [eval []] should be [] then that would require both EVAL to be VOID and REDUCE to vaporize them:
>> if false ["not"]
== ~void~ ; anti
>> reduce ["Bear in mind this will" if false ["not"] "make you a Red heretic"]
== ["Bear in mind this will" "make you a Red heretic"]
(It would still be possible to use REDUCE/PREDICATE and use a predicate function that errors on voids.)
I don't know how pivotal the particular point of eval []
is...
I don't really think we have code examples where this comes up all that often, which is probably why it hasn't been given that much thought.
OTOH the REDUCE default behavior does come up, I just don't tend to use REDUCE that often compared to COMPOSE. reduce ['x: 1 + 2] seems awkward compared to compose [x: (1 + 2)]. So it's like the only time I would use REDUCE would be to build the "block of precisely N values", and the restriction hasn't bothered me so far.