MAP-EACH + generic Identity Swapping vs. REMOVE-EACH

REMOVE-EACH is a somewhat problematic operation, in that it is doing a low-level manipulation of an array's contents...and you don't want to expose any intermediate states that aren't valid.

The efficiency of it is questionable...e.g. if you have an array that is 1,000 items long and you remove half of them, your array will now have 500 unused slots. Also, each time you remove an item you have to slide the rest of the array down...otherwise you leave an array which may have outstanding references in a potentially invalid state.

Ren-C went to some extremes to try and make REMOVE-EACH "rigorous". But it seems that it might be better to just write something like

remove-each: func [
    {Removes values for each block that returns true.}

    return: "Number of removed series items, or null if BREAK"
        [<opt> integer!]
    'vars "Word or block of words to set each time (local)"
        [blank! word! block!]
    data "The series to traverse (modified)" ; should BLANK! opt-out?
        [<blank> any-series!]
    body "Block to evaluate (return TRUE to remove)"
        [<const> block!]  ; !! Should support ACTION!
][
    if empty? :body [body: [void]]  ; GROUP!s vaporize when empty, address it

    let mp: either block? vars [:map-each/splice] [:map-each]

    let new-data: mp (vars) data compose/deep [
        if not (as group! body) [get/any '(vars)]
    ]
    if null? new-data [return null]  ; BREAK

    let diff: (length of data) - (length of new-data)
    swap-contents data new-data
    return diff
]

This hinges on the SWAP-CONTENTS low-level operation (better name sought), which would simply take the guts of the new series and swap it out with the old series. Code for this already exists.

What this means is that any code which accessed the original array during the removal process would see it as the pre-modified form. Which is basically what the Ren-C bulletproofing did, just much more awkwardly. :-/

REMOVE-EACH isn't all that terribly common, and the acrobatics required to make it safe aren't really a good use of time...especially to port here in stackless. It's better to invest more into making MAP-EACH stackless and rigorous, and spending time on more important problems.

Trying this out, there are a couple of problems.

One is the general problem I've mentioned before, of when you try to incorporate additional code with a loop's body...of the binding of the variables vs. the names of the constructs you're adding in, summarized here:

Compatibility MAP-EACH and problems therewith

The other problem is that MAP-EACH as written currently always returns a BLOCK!. (This now reminds me of why REMOVE-EACH's implementation was such a pain and not written in terms of MAP-EACH in the first place.)

So... this needs some deeper thinking. :-/