I realized this same issue "applies" to SPECIALIZE.
Right now, SPECIALIZE is very lax. It binds the block of specializing code into the frame it is specializing. You can run loops or do whatever you want. This is not like APPLY... which does its own dialected interpretation of the block.
If SPECIALIZE runs generalized code in the frame, you would have to use lifted assignments to set the fields (^xxx: ...). If it was just dialected and mandated you write the code as [arg1: ... arg2: ...]
then it might try the strategy I'm suggesting, where undecorated assignments decay, and ^arg:
assignments did not. (This would present a thorn for specializing with a raised error, since a strict format would have nowhere to put a TRY...)
This is a tough call. I can see uses for both kinds of operations, and that goes for APPLY as well (I called the run-arbitrary-code-version "APPLIQUE").
It would be nice if you could SPECIALIZE based on just order of args without naming them, like specialize add/ [5]
... perhaps even leveraging trash to skip slots as specialize subtract/ [~ 10]
(this starts to tread on the turf of POINTFREE, but that is proposed as a more complex operation that can do more than one layer of specialization).
(As a quick aside, I'll mention that maybe it would be possible to bind things like 1:
and ^2:
such that they could be used in SPECIALIZE or APPLY to refer to that Nth argument. I can imagine ways this could work, but at this point it's just imagination.)
Common Case Likely Favors Dialected Interpretation
Experience dictates that the most common uses of specialize are things like:
first: specialize pick/ [picker: 1]
It seems like a shame for it to be any worse than that. Further, in this dialected interpretation I know how to make things like 1:
and ^2:
work--it's trivial because there's no binding in play, you're just walking a block and filling in a known FRAME!, grabbing a SET-XXX and then doing one step of eval each time. This also means you could write something like:
picker: 10
first: specialize pick/ [picker: picker - 9]
...since there's no binding needed for the frame fields, you can assume each expression being evaluated is bound in the active environment.
So what to call the version that binds a frame, and makes you use ^picker:
but lets you write more freeform code? It could be specialize:freeform
or specialize:code
or something, shorthanded as specialize*
. Then APPLY would have a parallel notation (APPLIQUE was never meant to stick around...)