Iterating ACTION! vs. Iterating FRAME!

We know what iterating a FRAME! has to do

It has to give you the values of the frame, as if it were an object:

>> f: make frame! append/

>> f.series: [a b c]
>> f.value: [d e]
>> f.dup: 2

>> for-each [key val] f [
       print [mold key "=>" (mold cond val) else ["; null"]]
   ]
series => [a b c]
value => [d e]
part => ; null
dup => 2
line => ; null

No surprises there.

But Iterating ACTION! Has Competing Ideas

It might seem "useful" to say that iterating an ACTION! calls the action... and uses its results as the stuff you're iterating over.

But I've been thinking that when you PICK a field out of an ACTION! (antiform of FRAME!), you get the parameter:

>> append.value
== &[parameter! [<opt> element? splice!]]

>> append.dup
== &[parameter! :[any-number? pair!]]

That's effectively a GET:DUAL of the frame elements.

That is very useful. And if that's what PICK-ing gives you back it seems it's what a FOR-EACH should give you back. That's the consistent (and useful) behavior.

So enumerating an ACTION! could enumerate the parameters of that ACTION!. And I think that's probably what it should do.

This would mean that you'd have to do some kind of transformation on an ACTION! to get an iterator of some kind.

Could ITERATOR! be an antiform of OBJECT!?

:thinking:

This would allow transformations between OBJECT! <=> ITERATOR!

When viewed as an object, you could see the members and functions just like anything. But when viewed as an ITERATOR!, things like FOR-EACH would know to treat them differently and not enumerate the fields.

Maybe this answers the age-old "what is a PORT! question"

I've never known what a PORT! actually "is". But one thing I have known that if it is too "object-like" then you wind up with questions about which verbs that objects handle that it does... and which ones it wants special handling for.

Turning ACTION! => ITERATOR! Would Wrap The ACTION!

If you wanted to use an action to feed values to a FOR-EACH, there'd be "an app for that".

Maybe GENERATOR and YIELDER wouldn't return ACTION! at all, but an already-wrapped ITERATOR!.

This would free up ACTION! enumeration to give you the PARAMETER!s.

A nuance here is that if you do for-each [key param] action/ you'll get a value for PARAM that's a PARAMETER!... but if you do get key that will give you NULL.

The issue is that the WORD! you get in KEY is bound into the FRAME!, and there's no way to say "bind in such a way that you look up duals".

:thinking:

This can't be addressed by a GETTER function, because KEY gets a WORD!. You want something more indirect... e.g. the thing KEY looks up to would have to be a GETTER that fetched the parameter as a DUAL.

Going to have to think about it.

But saying that append.dup has to be NULL "for the sake of consistency" does not seem like the right tradeoff.

1 Like