Why Are Loop Variables Taken Literally?

Significant thought was put into this question, and using the Rebol2 convention wasn't just a matter of "keeping the status quo".

To make a long story short, the needs of the "iteration variable dialect" were such that the decorations had to be used in ways that their evaluator behavior wasn't compatible with, e.g.

for-each var data [...]  ; make new variable named "var", non-meta

for-each $var data [...]  ; reuse existing variable

for-each 'var data [...]  ; make new variable named "var" and don't bind

for-each '$var data [...]  ; reuse existing variable and don't bind

If the iteration variable parameter were not literal, you can't convey the notions because both 'var and $var evaluate to undecorated var. And '$var would evaluate to $var where you could get a signal to reuse the variable, but it wouldn't be bound so you couldn't act on it.

As it turns out, you actually get a bit of an advantage of not creating stray bindings if you use the quoted form. So if you think it reads better at the callsite, you're in luck--especially since doing things like COUNT-UP don't have bindings matter anyway.

But even if the bindings do matter... you can still put your loop variable in a block, if you feel that makes it more clear that it's being dialected.

>> a: 10 b: 20 c: 30

>> for-each [var] [a b c] [print [mold var "is" mold get var]]
a is 10
b is 20
c is 30

Most Rebol programmers would bristle at being required to do that. :man_shrugging:

Admittedly it's pretty strange to read a callsite like for-each '$var and find out that rather than passing unbound material, you've actually passed a bound variable to FOR-EACH. But the need for composable decorations forced my hand... there's only so many parts!

1 Like