C-style for loops in REBOL
rebol, rebol3
Solution
Because of the rebol3 tag, I'll assume this question pertains to Rebol 3.
Proposed "CFOR" for Rebol 3
For Rebol 3, there is a proposal (which got quite a bit of support) for a "general loop" very much along the lines of a C-style `for` and therefore currently going under the name of `cfor` as well: see CureCode issue #884 for all the gory details.
This includes a much refined version of Ladislav's original implementation, the current (as of 2014-05-17) version I'll reproduce here (without the extensive inline comments discussing implementation aspects) for the sake of easy reference:
cfor: func [ ; Not this name
"General loop based on an initial state, test, and per-loop change."
init [block! object!] "Words & initial values as object spec (local)"
test [block!] "Continue if condition is true"
bump [block!] "Move to the next step in the loop"
body [block!] "Block to evaluate each time"
/local ret
] [
if block? init [init: make object! init]
test: bind/copy test init
body: bind/copy body init
bump: bind/copy bump init
while test [set/any 'ret do body do bump get/any 'ret]
]
General problems with user-level control structure implementations in Rebol 3
One important general remark for all user-level implementation of control constructs in Rebol 3: there is no analogue to Rebol 2's `[throw]` attribute in R3 yet (see CureCode issue #539), so such user-written ("mezzanine", in Rebol lingo) control or loop functions have problems, in general.
In particular, this CFOR would incorrectly capture `return` and `exit`. To illustrate, consider the following function:
foo: function [] [
print "before"
cfor [i: 1] [i < 10] [++ i] [
print i
if i > 2 [return true]
]
print "after"
return false
]
You'd (rightly) expect the `return` to actually return from `foo`. However, if you try the above, you'll find this expectation disappointed:
>> foo
before
1
2
3
after
== false
This remark of course applies to all the user-level implementation given as answers in this thread, until bug #539 is fixed.
Problem
I attempted to write a C-style for-loop in REBOL: ``` for [i: 0] [i < 10] [i: i + 1] [ print i ] ``` This syntax doesn't appear to be correct, though: ``` *** ERROR ** Script error: for does not allow block! for its 'word argument ** Where: try do either either either -apply- ** Near: try load/all join %/users/try-REBOL/data/ system/script/args... ``` Does REBOL have any built-in function that is similar to a C-style for loop, or will I need to implement this function myself? The equivalent construct in a C-like language would look like this, but I'm not sure if it's possible to implement the same pattern in REBOL: ``` for(i = 0; i < 10; i++){ print(i); } ```