I'm hard pressed to think of what else it would do. The colon and the concept of "chaining" kind of suggests it.
I've biased the system to error on applying Sigils to things that already have them, because I think that's too permissive, and leads to misunderstandings:
>> x: @foo
>> lift x
** Error...
>> lift:force x
== ^foo
So I'd probably suggest this operator error by default as well.
It could work with GROUP!s and evaluate them, but it might be noisier than just using PIN.
Same number of characters. I would usually prefer the latter as the parentheses take it from "slightly and relevantly symbol-y" to "more symbol-y than it need be". Also with 4 inline cells it has better locality (vs. a 2-element CHAIN! with a 3-element GROUP! in it.)
But, good to have options. Also, since you can't assign Sigils, maybe the operator could stand alone:
>> @: pick stuff 2
== @baz
Looks like an assignment, but... Someone might like it. (I don't )
So I think this actually has to be something different... namely, the sought-after "Sigil Composition"
Since only one Sigil can be applied on an Element at a time, we could use this to have more than one. Then, you get the behavior of what the Sigil would have done if it were on the item.
Let's say you wanted to get a bound meta-WORD!:
>> $:^foo
== ^foo ; bound
Without this you'd have to do something like use the isolated $ Sigil ("BIND HERE") with a quoted item:
>> $ '^foo
== ^foo ; bound
Admittedly it's not much more typing in that case. But the point isn't the typing... the point is being able to represent both notions on a single Element, where if you do one PICK out of a block you can get back a single entity that conveys both ideas.
As discussed, this is important in places like FOR-EACH variables. Each Sigil means something different, e.g. @ means "reuse the variable, don't create a new one", and ^ means "lift the variable". What if you need both?
let foo
for-each [@:^foo] [a b c] [...]
assert [foo = the 'c] ; visible outside loop
So @bradrn was correct. But... I believe I was too: I did not disagree on the need for multiple intents, I just downplayed its importance... saying I simply didn't see a way to do it outside of using structure via BLOCK!, which would work in the cases it came up.
But CHAIN! answered many of the issues. It's like using BLOCK!, in that it has a defined structure. But unlike BLOCK! that needs [ and a ] at a sparse point to decorate, it only needs : to stick a Sigil on, at the location of the Sigil.
It has the property I was maintaining needed to be true, that a value has only one answer for its Sigil. As such:
>> type of first [@:^foo]
== ~{pinned!}~ ; antiform (datatype)
It's a PINNED!, and its locus of control in the evaluator comes from what PINNED! does, e.g.
>> @:^foo
== @:^foo ; bound
I don't know if it's a great idea to become too casual about it, but:
>> x: @foo
>> lift x
== ^:@foo
My instincts would be that it should require a refinement, you changed the fundamental type... lift:multi ?
(I bias things for safety first, usually... because it's easier to relax them later than it is to add the restriction later.)
I will point out that this becomes contentious with "what if you wanted a bound leading-colon meta-word":
>> $:^foo
== :^foo
It can't do both. (This was also a problem with the decoration idea.)
Here we also run into ambiguity of what UNLIFT should do:
>> unlift first [^:@foo]
== ??? ; should it be :@foo or @foo
This will need some consideration. I think breaking the uniformity here could very likely be worth it, so I'll start scrutinizing the use cases to determine if that is true.
There are many instances where certain lexical forms do something irregular. I think it's not as bad if they do it than if the fundamental operations do it (you wouldn't want BIND to break the rules for a specific type). Though the lines can be fuzzy.