The re-imagining of DO/NEXT is on its way to working. But we clearly don't want to call it DO/NEXT anymore. (I'm not as much concerned about changing the meaning of DO/NEXT in an incompatible way as I am that I don't like one version of DO returning an evaluation product, while another returns a series position--that's confusing.)
The old parameterization of DO/NEXT--where it puts the updated series position into a variable passed by reference and returns the evaluation product--has to die. It's an incomplete interface in a world with "invisibles". We don't want it.
What I think the best idea to do is to call the routine EVAL. "A DO of a BLOCK! is the result of several successive single EVAL steps in the evaluator." That seems nice.
Concept here is that plain EVAL won't give you a result, it will just run code and toss the evaluative by-product:
>> code: [print "hi" 1 + 2]
>> eval code
hi
== [1 + 2]
>> eval code
== []
>> eval code
;-- null
If you want the evaluative result, you'd use EVAL/SET. So a typical DO loop might look like:
while [block: try eval/set block 'var] [
...
]
(Remember, you are responsible with pre-loading var with a value--or null--that you want to correspond to what var would be if it happens to never successfully run an eval/set. Sometimes this is best to be #[void], sometimes null, or whatever the circumstance calls for.)
But the current EVAL also exposes a single evaluator step. It's a weird interface that runs "inline"... it takes one ordinary argument that's the head of the evaluation, and then gets its arguments from the callsite:
>> eval :add 1 2 ;-- historical EVAL
== 3
>> eval quote x: 100 ;-- historical EVAL
>> print x
100
I've been wondering though if maybe we should call this INLINE. Because really that's what you're asking it to do...it isn't so much that the EVAL function is taking arguments and "running a single evaluator step". It is splicing the material into the stream of execution.
>> x: quote foo:
>> inline x 100
>> foo
== 100
A little bit quirky but it seems to make sense. And it offers the advantage of DO/NEXT not being a parameterization that has to accept everything DO does. (Does do/next http://example.com/script.reb 'pos
actually make sense? Can everything that offers a DO interface guarantee that it meaningfully can give back a position into the thing that was done? Or that it even should--it may violate encapsulation...)