Taking $VARIABLES To Fold Mutation Into A Native For Speed

I've spoken about the need to optimize the GLOM function, which is a critical piece of UPARSE.

Because GLOM was "append-like" it would take SPLICE! or single values. But I realized that when speaking the language of historical APPEND, most of the code for glom wound up looking like:

pending: glom opt pending spread opt subpending

Once I switched to using empty splice (new "none") instead of NULL for the base case, I didn't have to OPT it. And switching to a mode where you passed in either a BLOCK! or a QUOTED! fits the bill:

pending: glom pending subpending  ; typical, auto-splices

pending: glom pending quote item  ; add single item as-is

But looking at the "how fast can this native be" question, I asked myself: what if we passed the variable in for the accumulator, not the value

glom $pending subpending

glom $pending quote item  ; add single item as-is

A Generalized Speedup Possibility For Natives

If GLOM were usermode, you'd just be slowing things down...because you'd be using a SET function call, which is less efficient than the SET-WORD at the callsite.

But with a native, that's not the case. You avoid an evaluation step and save some time.

At a source level, one can view it as both good and bad. It obfuscates the mutation... but it's shorter.

I Wouldn't Suggest This Spreading Far In The System

I don't think one should reach for this as a tool very many places.

GLOM is a weird function that is targeting general efficiency more than it is clarity. It's a specialized tool that actually fiddles the underlying identities of the series it has to try and squeak out an advantage due to it being the implementation detail of UPARSE's rollback mechanisms for things like COLLECT and GATHER. I don't mind making it a little more weird.

Well, maybe it's more useful than I think...

For instance, NEXT is non-mutating.

iter: next iter
iter: my next

But... consider having the alternative option:

next $iter

That's somewhat compelling, to me. For example, here's a code snippet from UPARSE:

rules: next rules
if word? rules.1 [
    rules: add-let-binding rules rules.1 ()
    rules: next rules
    continue
]

Imagine if you could have written:

next $rules
if word? rules.1 [
    add-let-binding $rules rules.1 ()
    next $rules
    continue
]

I'll stress that this would only be an option for those who wanted to use it. It would still work the other way.

But I know which I would use! The $ does not scare me, and if it performed better I'd prefer it...

Note that historical Rebol could do this, however the slightness of the quoting makes it seem less wise:

; Redbol
next 'rules
if word? rules/1 [
    add-let-binding 'rules rules/1 none
    next 'rules
    continue
]

Also, Ren-C has some pretty killer tech waiting in the wings to make "function that takes a variable you can write back to" easier to create... with a $parameter convention... stay tuned!