TAG!s Angle Brackets: *They Aren't There!*

Implementation-wise, the delimiters of tag have been quite the thorn.

Are they there or not?

In Rebol2, Red, R3-Alpha...

>> find <abcd> "c"
== <cd>

>> find <abcd> ">"
== none

Not there!

Or are they? Reverse the arguments, and in Rebol2 and Red, they seem to magically appear:

>> find "ab<c>d" <c>
== "<c>d"

But... this was not the case in R3-Alpha...

r3-alpha>> find "abcd" <c>
== "cd"

r3-alpha>> find "ab<c>d" <c>
== "c>d"

I know things have gone back and forth with people believing deeply in their little hearts that they are happier when routines act like the delimiters are there...

But for the baseline behavior: I have come to believe R3-Alpha is right. They're string delimiters, and incidental to the default purpose, just as quotes are.

If you start looking at TAG! as it truly is--just another string class with different delimiters--it simplifies the mental model and the implementation model. You can truly just use it like another string, and it suddenly becomes consistent.

Of course, it's still nice to be able to match the molded form of a tag.

But... why stop at tags? :thinking: Why not have a syntax to match the molded form of anything?

In strings, where you can't match list elements literally anyway:

>> parse "<a> 100 (b c)" ['<a> space '100 space '(b c)]
== (b c)

(The synthesized product may be more interesting, too. As a reminder, Ren-C has taken words that might be better as variable names like END and uses plain tag as instead, or to synthesize the parse input, etc.)

>> parse "<end> asdf" ['<end> to <end> <input>]
== "<end> asdf"

I don't know whether that is best done as just a PARSE feature, or if quoted things need to be searched for literally by FIND.

>> find "ab<c>d" <c>
== "c>d"

>> quote <c>
== '<c>

>> find "ab<c>d" quote <c>
== "<c>d"

>> find "ab<c>d" mold <c>  ; one fewer character
== "<c>d"
1 Like

But what if (for whatever reason) you did want to match the quoted tag '<end>, say, in an input block? I don’t think there’s much advantage over just writing ["<end>" to <end> <input>], which is only one character longer, and strikes me as being clearer.

You can say:

>> parse ['<end> asdf] [''<end> to <end> <input>]
== ['<end> asdf]

Or alternately, you can use LITERAL:

>> parse ['<end> asdf] [literal '<end> to <end> <input>]
== ['<end> asdf]

Abbreviated:

>> parse ['<end> asdf] [lit '<end> to <end> <input>]
== ['<end> asdf]

Sure, I realise that you can do all these things. I’m just thinking that it seems less confusing to write their string representations as strings.

It's a choice. The systemic pattern of letting you use quoted things to represent their molded representations gives you an economy I like:

>> left: "foo"
>> right "bar"

>> unspaced [left '# right]
== "foo#bar"

>> unspaced [left "#" right]
== "foo#bar"

It's 3 fewer "ticks".

Of course, can't work for everything:

>> unspaced [left "[" right]
== "foo[bar"

But where it does work, I think it's good.

People can make up their own minds on when it's more confusing than it is helpful. Some might like it for string formation, but not string parsing. Maybe even if a tag is a common parse instruction it might be in double quotes, while something like <br /> would be obviously not a parse instruction and matched by an apostrophe. :man_shrugging:

OK, I find that example more convincing than the TAG! one.