So the meaning of @ has come into focus somewhat interestingly as "leave that alone".
Even its usage in UPARSE has become a way of passing a block to a combinator by value without applying the block combinator rules. This makes @[xxx] able to act as a shorthand for ([xxx])...but it's up to a combinator to decide if it wants to distinguish them or not.
So What Should The @Branch
Meaning Be?
The meaning I had been using previously was "don't isotopify the branch":
>> if true [null]
== ~null~ ; isotope
>> if true @[null]
; null
This doesn't seem to fit anymore. I'd proposed an alternative, which is a bit weird...but if you consider /x as being "optional x"...as in refinements...maybe not so weird:
>> if true [null]
== ~null~ ; isotope
>> if true /[null]
; null
I guess I can live with that.
If you're going to go with the "already evaluated" concept, that might lead you down the path of one of these options:
>> if true @[1 + 2]
== [1 + 2]
>> if true @[1 + 2]
== @[1 + 2]
>> if true @[1 + 2]
== 2
To explain why I'd make the last suggestion: it is along a line of thinking do @[1 + 2] would be 2...as if it had run the process of DO-ing inertly and the last value dropped out. This would just be part of a system of thinking where an @ block does what a plain block would if each evaluation step was just inert.
And before we think too hard on that, let's remember that currently quoting is permitting reasonable enough ways of saying the first two:
>> if true '[1 + 2]
== [1 + 2]
>> if true '@[1 + 2]
== @[1 + 2]
The only place you get a savings here is when @[1 + 2] => @[1 + 2] for a branch, because you type one less character without the quote mark to get that.
A Different Tactic: Mostly The Same, Just Tweaked?
I'll put forth the idea that if you have a type that some functions have a meaningful stake in treating different while others don't... it might be worthwhile to accept both and just treat them the same. This reduces the concerns of people needing to strip the marker off.
So @[...] and [...] could be treated the same when it's a branch. It's one idea.
There could be a twist: At one point I had suggested that the @(...) could be leveraged as the difference between passing a branch inertly and not:
>> either false (print "A", [print "AA" <a>]) (print "B", [print "BB" <b>])
A
B
BB
== <b>
>> either false @(print "A", [print "AA" <a>]) @(print "B", [print "BB" <b>])
B
BB
== <b>
Here the focus on inertness is "inert during the parameter gathering phase", but once that phase is over the normal behavior kicks in.
You might recall I'd previously suggested the inert behavior become the default behavior for GROUP!, and you'd use :(xxx) to insist on the evaluation... tying that in to the :param parameter convention. But :param
seems to have a new destiny as the answer to REPEND-like functionality, so shifting to this concept might be a good idea.
And we could go ahead and throw in the idea of a shorthand for getting a variable with that:
>> x: 10
>> if true @x
== 10
Seems plausible...
Though if you're wondering why you wouldn't just make the branch:
>> either false [print "A", print "AA" <a>] @(print "B", [print "BB" <b>])
The concept is that it's code that generates a branch, so you're saving yourself a DO, and locating where to put that do.