COLLECT Mutation Semantics: KEEP vs. KEEP/ONLY

When reimplementing COLLECT for UPARSE on top of the "pending" model, I mentioned a potential avenue for optimization by not immediately splicing blocks, but keeping them in a list and then merging the whole list together if-and-when the COLLECT got to the success point:

The idea of saving splicing until the end might sound good, but... it doesn't work if we presume mutations.

Just imagine a delaying implementation of ordinary COLLECT:

>> delayed-splice-collect [
      block: [a b c]
      keep block
      clear block
      insert block [d e f]
      keep block
  ]
== [d e f d e f]

That's not what we expect from today's COLLECT.

Though if you're not splicing, you expect mutations to affect what you've already collected. It's true in all Redbols today, since you're keeping the block by identity:

red>> collect [
         block: [a b c]
         keep/only block
         clear block
         insert block [d e f]
         keep/only block
      ]
== [[d e f] [d e f]]

Persistent Vector Looks Awfully Tempting :face_with_monocle:

Looking at things like this is always a throwback to saying "mutable state by default is garbage". But it depends on what example you're looking at. Sometimes it's good, sometimes it's bad.

I guess the thing is to just explore what the good parts are. Maybe someone will blend in some Clojure bits at some point in a derivative...but that person is not going to be me!

2 Likes