So, this is somewhat trivial. But what if you wanted a function that instead of RETURN ending the function, it just added to the results and moved on? We might call this a COLLECTOR.
Let's imagine that we like KEEP better than renaming to RETURN
collector: func [spec block] [return func spec compose [collect (block)]]
; ^-- Ren-C semantics for COMPOSE, BLOCK! only splices if ((...))
c: collector [x] [
keep x + 1
keep x + 2
keep x + 3
]
>> c 10
== [11 12 13]
>> c 20
== [21 22 23]
>> c 30
== [31 32 33]
(Note: This is an interesting example of the "what do I do with a BLOCK!, splice by default or not?" I still find this to be a central question. I'm pretty confident that differentiating the splice case in COMPOSE visually with ((...))
is a good move. But I'm still on the fence about what the bigger story is. Lately my leaning is that we do have modal parameters, e.g. keep @value
will act the same as keep/only value
, but plain KEEP has the variance in behavior for blocks that it has today...risky though it is. People just learn to live with it or use @ or /ONLY habitually.)