The Pending New Meaning of GET-XXX!

If you've been following along with things like The Solution to Block Splicing or Activated Actions, it seems to suggest that GET-WORD! and friends would no longer be necessary.

  • If you have a non-isotopic value (including an ACTION!), you access it with a plain WORD! and it's fine--the obvious code just works.

  • If you have an isotopic value, you use a META-WORD! and get its non-isotopic form, and work with that. (It will be inert, so you "won't need" GET-WORD! on it...)

So I'm going through all the non-Redbol code and eliminating the use of GET-WORD!, GET-PATH!, and GET-TUPLE!

It's pleasing to see the improvement.

But Like I Said, You Can't Wish Away Complexity...

When you have a case that turns out to be complex, there's a new twist...you get quoted/meta items, not plain items:

>> unsafeobj: make object! [x: 10, /y: func [] [print "Boo!"]]

>> for-each [key ^val] unsafeobj [print ["meta" key "is" mold val]]
meta x is '10
meta y is #[action! []]

Now you can no longer just test with INTEGER? VAL, because VAL is quoted.

So the new concept I have for :val is that it mean unmeta val. This way you can say:

if integer? :val [print "It was an INTEGER! before the ^META"]

Wait, Isn't This The Same Situation As Before?

You might ask if we've just come full circle, since you have to start using a mark on variables in order to correctly handle situations with active actions.

But you don't get into this situation unless you consciously ask for it... your code is correct by default, and the active actions can't just "sneak up on you".

And it's nice that the values aren't active...you're not risking a function being called without you knowing about it. Instead you have a QUOTED! value, which has a weird type that will give more obvious errors if you forget to unmeta it.

It Also Gives A Notation For Splices

I mentioned we need some way to meta a splice, in such a way that it will evaluate back to a splice again. The block form gives the answer for this:

>> var: :[d e]
== :[d e]  ; isotope

>> temp: ^var
== :[d e]

>> do compose [var: (temp)]
== :[d e]  ; isotope

>> append [a b c] get/any 'var
== [a b c d e]

Parameterized Evaluator Will Be Needed For Redbol

I'm pretty gung-ho on keeping the Redbol tests running. So this really lights a fire under the need to start acting on parameterized evaluation.

When the body of a Redbol "FUNC2" is evaluating, it needs to imbue that body with the behavior that the :word just gets the value.

I'm not sure what to do about isotopic actions and Redbol emulation. :-/ It creates an interoperability issue when mixing code. The "pure" way of doing it would give Redbol a truly separate context, where all of its LIB definitions were plain ACTION!s...that its evaluator would run from word references. It's probably better to instead have Redbol only deal with ACTION! isotopes...telling it that they are plain ACTION!s.

Necessitates A New Name?

In a way, naming the parts for their behaviors has always been a bit of a bad idea. Because you're supposed to be able to redefine them to do whatever you want. (A SET-WORD! doesn't have to set anything, and a GET-WORD! doesn't have to get anything. So why aren't they COLON-WORD! and WORD-COLON! ?)

And above I talk about Redbol behavior, where they'll act as before. :-/

If I could, I've said that I'd rather the ^META and :UNMETA operations be noted with up arrows and down arrows, and perhaps be called "UP-WORD!" and "DOWN-WORD!".

>> for-each [key ↑val] unsafeobj [if integer? ↓val [print "Integer found!"]]
Integer found!

But, the ASCII benefits win out:

>> for-each [key ^val] unsafeobj [if integer? :val [print "Integer found!"]]
Integer found!

Anyway, the name isn't the most important thing... but just another thing to work through.

1 Like