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
петля.