GET-BLOCK!, GET, and REDUCE

I have restored the behavior that GET-BLOCK! acts as REDUCE

>> :[1 + 2 10 + 20]
== [3 30]

This means that if you're dealing with a literal block, you can avoid functions like REPEND.

>> append [a b c] :[1 + 2 10 + 20]
== [a b c 3 30]

And I think it means we can be happy enough defining JOIN as not reducing by default:

>> data: [a b c]

>> join data [1 + 2 10 + 20]
== [a b c 1 + 2 10 + 20]

>> data
== [a b c]

If you want to reduce, you ask for it:

>> data: [a b c]

>> join data :[1 + 2 10 + 20]
== [a b c 3 30]

>> data
== [a b c]

This case of literal information actually comes up rather often. For those who prefer writing out the word REDUCE even in literal cases, no problem.

What about SET and GET natives and BLOCK?!

The thing I had been fretting about was if SET of BLOCK! and a GET of BLOCK! didn't do the same thing as a SET-BLOCK! and GET-BLOCK! would.

Yet today know that SET-BLOCK! has the behavior of multi-return, and that's been a huge win. It's not possible to unify that behavior for what it means to combine the SET native and a BLOCK! value.

And as I've mentioned, historical Rebol2 and Red do not have meaning for a GET of a BLOCK!, it's an error:

red>> a: 10
red>> b: 20
red>> get [a b]
*** Script Error: get does not allow block! for its word argument

So it's not [10 20] as one might expect (though you might argue it's just an oversight and they'll add it some day).

But I don't like these operations and I've explained why: not all variable states can be put into block elements. You can't put NULL and you can't put BAD-WORD! isotopes.

The workaround I came up with is called UNPACK and I think it really sorts out the various problems that GET and SET of BLOCK!s invariably introduce.

2 Likes