I'd said "It's time to bring back APPLY".
...and by "it's time" I apparently meant "within the next year, maybe?"...
But better late than never, right? It's in!
Refinements Can be Provided In Any Order
[a b c d e d e] = apply :append [[a b c] [d e] /dup 2]
[a b c d e d e] = apply :append [/dup 2 [a b c] [d e]]
[a b c d e d e] = apply :append [[a b c] /dup 2 [d e]]
[a b c d d] = apply :append [/dup 2 [a b c] [d e] /part 1]
[a b c d d] = apply :append [[a b c] [d e] /part 1 /dup 2]
Any Parameter (Not Just Refinements) Can Be Used By Name
Once a parameter has been supplied by name, it is no longer considered for consuming positionally.
[a b c d e] = apply :append [/series [a b c] /value [d e]]
[a b c d e] = apply :append [/value [d e] /series [a b c]]
[a b c d e] = apply :append [/series [a b c] [d e]]
[a b c d e] = apply :append [/value [d e] [a b c]]
Commas Are Ok So Long As They Are Interstitial
[a b c d e d e] = apply :append [[a b c], [d e], /dup 2]
[a b c d e d e] = apply :append [/dup 2, [a b c] [d e]]
>> apply :append [/dup, 2 [a b c] [d e]]
** Script Error: end was reached while trying to set /dup
Giving Too Many Arguments Defaults To An Error
>> apply :append [[a b c] [d e] [f g]]
** Script Error: Too many values in processed argument block of APPLY.
If you want, you can ask it to /RELAX
>> apply/relax :append [[a b c] [d e] [f g]]
== [a b c [d e]]
Refinements Must Be Followed By A Non-Refinement
>> apply :append [/dup /part 1 [a b c] [d e]]
** Script Error: end was reached while trying to set /dup
But you can pass refinements as arguments to refinements...just use a quote!
>> tester: func [/refine [any-value!]] [refine]
>> apply :tester [/refine '/ta-da!]
== /ta-da!
No-Arg Refinements Permit OKAY and NULL
Remember: the EVAL FRAME! mechanics do not change anything. So if a refinement doesn't take an argument, the only legal values for that refinement in the frame are OKAY and NULL.
>> testme: func [/refine] [refine]
>> apply :testme [/refine okay]
== ~okay~ ; anti
>> apply :testme [/refine null]
== ~null~ ; anti
>> apply :testme [/refine 1020]
** Error: No-Arg refinements can only be ~okay~ and ~null~ antiforms
^META Arguments Are Accounted For
APPLY detects when a parameter is meta and will level it up...because the low-level frame mechanics aren't allowed to editorialize:
>> non-detector: func [arg] [arg] ; not a meta argument, isotopes illegal
>> apply :non-detector [pack [10 20]]
== 10
>> detector: func [^arg] [arg]
>> apply :detector [pack [10 20]]
== ~['10 '20]~
I know not everyone has gotten their heads around isotopes yet, but they are critical... this stuff was the missing link to making it all gel.