COMPOSE of TUPLE! and PATH! (and toplevel GROUP!)

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)
2 Likes

With changes to things like SET-GROUP becoming a CHAIN!, we now have a situation where we are getting this behavior:

>> var: $x

>> compose [(var): 10]
== [(var): 10]  ; hm, no substitution?

So this would see the (var): 10 as a subsequence and require :DEEP.

But I don't think DEEP should be necessary for this. So I imagine that sequences are considered to be part of the same level for the purposes of COMPOSE'ing.

By that rule, I would imagine this would not require DEEP either.