While rethinking the nature of arity-1 WHILE and shifting the arity-2 WHILE semantics to LOOP, it made me think that maybe this needs reordering.
>> for x each [1 2] [print ["running" x, x + 10]]
running 1
running 2
== 12
This would mean EACH [1 2] would be the generator, and X would be a property of FOR. That gives flexibility in defining FOR for other argument values. Integer could just count up:
>> for x 2 [
print ["running" x], x + 10
]
running 1
running 2
== 12
FOR X EACH and FOR-EACH X are the same number of characters, with the former having nicer visual possibilities. This is especially true when differentiating a block for variable names from the iterated variables:
for-each [a b] [1 2 3 4] [print [a b]]
for [a b] each [1 2 3 4] [print [a b]]
This makes EACH as a generator much clearer:
>> g: each [1 2]
>> g
== 1
>> g
== 2
>> g
; null
Under this setup, a FOR which did not use an EACH could reserve BLOCK! for other meanings, such as a dialect for ranges.
for x [1 to 10] [print [x]]
for x [1 thru 10] [print [x]]
But since that puts a lot of "logic" into FOR, we might make EACH the default semantics of a series with FOR and then make this dialect the weird case. Otherwise you're kind of wasting the short word on cases like strings. But it's hard to think of a good short name for that generator dialect:
for x yournamehere [1 to 10] [print [x]]
for x yournamehere [1 thru 10] [print [x]]
Anyway...if FOR was generalized in this way, it could free up REPEAT for something that might make more sense: namely "do the same thing N times". But this could be distinguished from loop by paying attention to the truthiness of the body:
>> n: 0
>> repeat 10 [ ; a WHILE variant, limited by a count.
print "Repeating"
n < 3
]
Repeating
Repeating
Repeating
Repeating
This combination of "heeds the count, but stops earlier if the body returns false" may seem odd. But this formulation could make repeating a rule N times in PARSE more clear when it's hidden behind a variable.