APPLY II: The Revenge!

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.

:dizzy: :dizzy: :dizzy:

2 Likes