C-стиль для петель в REBOL

Я попытался написать цикл for в стиле C в REBOL:

for [i: 0] [i < 10] [i: i + 1] [
    print i
]

Этот синтаксис не выглядит правильным, хотя:

*** 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...

Есть ли в REBOL какая-либо встроенная функция, похожая на цикл for в стиле C, или мне нужно будет реализовать эту функцию самостоятельно?

Эквивалентная конструкция в C-подобном языке выглядела бы так, но я не уверен, возможно ли реализовать тот же шаблон в REBOL:

for(i = 0; i < 10; i++){
    print(i);
}

5 ответов

Решение

Из-за тега rebol3 я предполагаю, что этот вопрос относится к Rebol 3.

Предлагаемый "CFOR" для Rebol 3

Для Rebol 3 есть предложение (которое получило немалую поддержку) для "общего цикла", очень похожего на стиль C for и, следовательно, в настоящее время идет под именем cfor также: см. выпуск CureCode #884 для всех кровавых деталей.

Это включает в себя очень доработанную версию первоначальной реализации Ладислава, текущую (по состоянию на 2014-05-17 гг.) Версию, которую я воспроизведу здесь (без подробных встроенных комментариев, обсуждающих аспекты реализации) для удобства:

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]
]

Общие проблемы с реализациями структуры управления на уровне пользователя в Rebol 3

Одно важное общее замечание для всех пользовательских реализаций управляющих конструкций в Rebol 3: аналога Rebol 2 не существует. [throw] атрибута в R3 пока нет (см. выпуск CureCode #539), поэтому такие пользовательские ("мезонинные", в Rebol lingo) функции управления или циклы, как правило, имеют проблемы.

В частности, этот CFOR будет неправильно захватывать return а также exit, Для иллюстрации рассмотрим следующую функцию:

foo: function [] [
    print "before"
    cfor [i: 1] [i < 10] [++ i] [
        print i
        if i > 2 [return true]
    ]
    print "after"
    return false
]

Вы (правильно) ожидали return на самом деле вернуться из foo, Однако, если вы попробуете выше, вы найдете это ожидание разочарованным:

>> foo
before
1
2
3
after
== false

Это замечание, конечно, применимо ко всем реализациям пользовательского уровня, приведенным в качестве ответов в этой теме, до тех пор, пока ошибка #539 не будет исправлена.

Оптимизированный Cfor от 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
  ]
]

Другая структура управления, которую большинство людей будет использовать в этом конкретном случае, это repeat

repeat i 10 [print i]

что приводит к:

>> repeat i 10 [print i]
1
2
3
4
5
6
7
8
9
10

Я вообще не пользуюсь loop очень часто, но его можно использовать в аналогичной степени:

>> i: 1 
>> loop 10 [print ++ i]
1
2
3
4
5
6
7
8
9
10

Это некоторые полезные структуры управления. Не уверен, что вы искали cfor но вы получили этот ответ от других.

Я реализовал функцию, которая работает так же, как цикл C for.

cfor: func [init condition update action] [
    do init
    while condition [
        do action
        do update
    ]
]

Вот пример использования этой функции:

cfor [i: 0] [i < 10] [i: i + 1] [
    print i
]

Для простого начального значения, верхнего предела и шага, следующие работы:

for i 0 10 2 
    [print i] 

Это очень близко к С for петля.

Другие вопросы по тегам