Yep, they're implemented!!! Go try them out!!!
Years ago, discussions circled around what was so special about WORD! and PATH! that they should be the only ones with LIT-XXX! forms. It seemed this was a bit that could equally apply to anything, e.g. group: '(1 + 2)
.
It took a while, but eventually a general and clever solution was discovered. There's no LIT-XXX!, just QUOTED! as a container for any type...with any level of quoting. It's done with neat tricks!
...but what about SET-XXX and GET-XXX?
In that same vein, we might ask why PATH! and WORD! are the only types with SET-XXX! and GET-XXX! forms. Aren't those just bits too?
GET-BLOCK! seems very useful if it would do a REDUCE in the evaluator. Instead of return reduce [x y] you could just say return :[x y]. SET-GROUP seems like it might be a little tidier too...
word: 'x
set word 1020
word: 'x
(word): 1020
It's only one less character. But whether you have a preference for one or the other visually, the second can be done faster; the evaluator doesn't have to look up SET to find the function, nor go through the trouble of filling function frames and dispatching. It's much lighter-weight.
Yet it seems a slippery slope...
GET-BLOCK! and SET-GROUP! sure seem useful, but if we look at this as more cases of the "lit bit", where does it stop?
If every type has a "get bit" and a "set bit", can you have both of them? How does this mix with the LIT-XXX forms? Is there a difference between a LIT-SET-PATH! and a SET-LIT-PATH?
What would a SET-URL! look like? How are the colons mixing up with literals that have colons in them? (:15 is a TIME! in the current world..., that would become a GET-INTEGER!, so what does a GET-TIME! look like?)
This foiled ideas of the past, like trying to get rid of SET-PATH! and GET-PATH! and just say, e.g. "a SET-PATH! is one with a SET-WORD! in its last slot". Because then to get x/1: you would need SET-INTEGER!, to get x/(y + z): you'd need SET-GROUP!, and it just seemed to go to chaos.
In the absence of a clear plan, we plodded along with the status quo, awaiting some moment of clarity.
Moment of clarity arrived: Just add BLOCK! and GROUP!
If we only allow SET and GET forms on containers, it's a clean model (no worries about intersecting with lexical rules of the contained types). And you get your dialected parts. Need a SET-INTEGER! ? Well, you no can has. But with containers, you get it all:
my-dialect [
[1]: "It's just as good, as `1:`, really!"
:(:15) "Even better, as if you want GET-FIFTEEN-MINUTES!, you can have it..."
[http://example.com/colons-legal-in-url:]: "Yup, colons are legal in URL!s"
(your multi-value expression here): "goes great with expressions!"
]
Then we stop. We get 4 new parts that are genuinely useful, that make the evaluator more expressive and run common functionality faster. If you find uses in your dialects--and you almost certainly will--so much the better.
The commit for them fixes flaws in the scanner
There were some things you couldn't make. In Rebol2/R3-Alpha/Red:
rebol2>> first [:a/(b + c)]
== a/(b + c):
rebol2>> first [:(a + b)/c]
** Syntax error: invalid "word-get" -- ":"
It might seem like it wouldn't be that hard to fix, but fixing it is a lot easier if you can just pass through a moment where the head of that block is a GET-GROUP! and then twiddle it into a regular GROUP! later. (That's how GET-PATH! works when it has a GET-WORD!-looking thing at the head). The scanner is already rather fiddly and throwing in more fiddly-bits is not forward-looking.
This lets that work basically for free, just a minor tweak on the previous method:
>> first [:(a + b)/c]
== :(a + b)/c
>> type of p: first [:(a + b)/c]
== get-path!
type of first p
== group! ;-- regular GROUP! as first element of GET-PATH!, perfect
They're awesome, you'll love 'em
Try them out and let me know what you think, and if you find cool new dialect applications! Some demos:
; GET-BLOCK!, doing a fast REDUCE
>> a: 10
>> b: 20
>> :[a b]
== [10 20]
; GET-GROUP!, getting a PATH!
>> o: make object! [f: 304]
>> path: 'o/f
>> :(path)
== 304
; SET-GROUP!, setting a BLOCK!
>> m: <before>
>> o: make object! [f: <before>]
>> block: [m o/f]
>> (block): [1020 304]
>> block
== [m o/f]
>> m
== 1020
>> o/f
== 304
; SET-BLOCK!, with a block on the right
>> a: _ b: _
>> [a b]: [10 20]
>> a
== 10
>> b
== 20
; SET-BLOCK! with a non-block on the right
>> a: _
>> b: _
>> [a b]: <thing>
>> a
== <thing>
>> b
== <thing>
I'm sure people will think of improvements, but that's for starters.
And note they'll get even better with mirror bytes, where (x): won't cost any more than x: !!! I'm relatively confident I can make that happen, some groundwork is done already.