I've described a new parameter convention that I call an @arg which could be supported by the evaluator. But here is a bit of code to implement the trick in present-day Ren-C:
old-append: :append append: function [ series :nosplice [<skip> sym-word! sym-path! sym-block! sym-group!] value [<...> any-value!] /only ][ switch type of :nosplice [ null [old-append/(only) series take value] ; no @... so act variadic sym-block! [old-append/only series as block! splicer] sym-group! [old-append/only series do as group! splicer] sym-word! sym-path! [old-append/only series get splicer] ] ]
This leaves splicing the default:
>> append [a b c] [d e] == [a b c d e]
But if you use an @... at the callsite it offers alternate ways of requesting /ONLY:
>> append [a b c] @[d e] == [a b c [d e]]
The trickery though is that it has to be a literal @... at the callsite. Indirectly that doesn't apply (if it comes from a reference or expression), it will append in the typical fashion, whatever that would be:
>> item: @[d e] == @[d e] >> append [a b c] item == [a b c d e] ; or should only plain BLOCK! splice?
The callsite permits conventional expressions for the plain case (now an /ONLY behavior), written out as a full evaluation (e.g. the argument is not quoted):
>> append [a b c] reverse copy [d e] == [a b c e d]
On the other hand, the /only cases are all going through a quoted argument...but these provide variations besides an @-block:
>> append [a b c] @item == [a b c [d e]] >> append [a b c] @(reverse copy item) == [a b c [e d]]
And again, these variations are visible at the callsite; they don't accidentally sneak in to run code as /ONLY if your callsite didn't make it look that way just due to some indirect value:
>> item: @(reverse copy item) == @(reverse copy item) >> append [a b c] item == [a b c reverse copy item] ; ANY-ARRAY! splice?
If you really do want to deliberately append an @... then you can do so with quoting (which you'd have to do for a WORD! or other evaluative type that you didn't mean "do something evaluatory with")