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 [ : "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.