Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C-style for loops in REBOL

Tags:

rebol

rebol3

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);
}
like image 836
Anderson Green Avatar asked Jan 28 '26 23:01

Anderson Green


2 Answers

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.

like image 173
earl Avatar answered Feb 01 '26 05:02

earl


There is an optimized Cfor by Ladislav Mecir

cfor: func [
  {General loop}
  [throw]
  init [block!]
  test [block!]
  inc [block!]
  body [block!]
] [
  use set-words init reduce [
    :do init
    :while test head insert tail copy body inc
  ]
]
like image 22
sqlab Avatar answered Feb 01 '26 04:02

sqlab



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!