While working on @BlackATTR's query, I noticed code that was making paths (now tuples) out of components via TO TUPLE! COMPOSE of a BLOCK!. Like this:
to tuple! compose [obj clauses (kwd.1)]
But did you know that COMPOSE can act directly on TUPLE! and PATH! You could instead just write:
compose $obj.clauses.(kwd.1)
It supports splices as well:
>> compose $(10 + 20)/a/b/(spread [c d e])/(reverse [g f])
== 30/a/b/c/d/e/[f g]
And if you remember that TUPLE! can be nested underneath PATH! (not vice versa) then you can COMPOSE/DEEP and handle mixed tuples and paths:
>> compose/deep $(10 + 20)/a/b.(spread [c d e])
== 30/a/b.c.d.e
Voids can vanish...so there can be fewer dots in an output tuple than in the input:
>> compose $a.(if false [b]).c
== a.c
Empty splices will vanish as well:
>> compose $a.(spread []).c
== a.c
You can't compose in NULLs as an important safety measure...central to the design!
>> compose $a.(select [x 10 y 20] 'b).c
** Script Error: non-NULL value required (see MAYBE, TRY, REIFY)
** Near: [a ** (select [x 10 y 20] 'b) c]
But don't forget about MAYBE as the way to convert nulls to void when that's what you meant!
>> compose $a.(maybe select [x 10 y 20] 'b).c
== a.c
You can also COMPOSE a GROUP!
In R3-Alpha, only BLOCK! would compose. Everything else was passed-through as-is, including GROUP!s (PAREN!s in their terminology)
r3-alpha>> compose quote (1 + (2 + 3)) ; R3-alpha QUOTE (modern THE)
== (1 + (2 + 3))
Red just doesn't allow it:
red>> compose quote (1 + (2 + 3)) ; Red QUOTE (modern THE)
*** Script Error: compose does not allow paren! for its value argument
So you'd wind up having to make BLOCK!s and then convert them:
red>> as paren! compose [1 + (2 + 3)]
== (1 + 5)
But in Ren-C, group composing works... it just leaves the top group as-is.
>> compose $(1 + (2 + 3))
== (1 + 5)