Здебільшого Factor виконує ітерацію через комбінатори, як-от each, map і count. Іноді, втім, найчистіший спосіб записати обчислення - це рекурсія, тобто слово, яке викликає саме себе.
Визначення : може викликати саме себе безпосередньо:
: count-down ( n -- )
dup 0 = [ drop ] [ dup . 1 - count-down ] if ;
5 count-down
! prints 5 4 3 2 1
if-empty (з sequences) - це природний базовий випадок рекурсії:
if-empty ( seq emptyquot nonemptyquot -- )
{ 4 0 9 } [ "empty" ] [ "got data" ] if-empty .
! => "got data"
emptyquot виконується, коли (порожню) послідовність уже знято зі стека; nonemptyquot виконується, коли послідовність ще лежить на стеку.
cond - ланцюжок гілок із перевіркамиКоли в нашій рекурсії більше ніж два випадки, cond (з combinators) допомагає зберегти код читабельним:
: classify ( n -- label )
{
{ [ dup 0 < ] [ drop "negative" ] }
{ [ dup 0 = ] [ drop "zero" ] }
[ drop "positive" ]
} cond ;
DEFER:
Визначення : може викликати саме себе безпосередньо, але коли два слова викликають одне одного, парсер бачить перше з них раніше, ніж існує друге. DEFER: резервує імʼя, щоб перше визначення могло скомпілюватися:
DEFER: even?
: odd? ( n -- ? ) dup 0 = [ drop f ] [ 1 - even? ] if ;
: even? ( n -- ? ) dup 0 = [ drop t ] [ 1 - odd? ] if ;
DEFER: також стає в пригоді, коли допоміжне слово природніше читати після слова, яке його використовує.
Ми ведемо щоденний облік того, скільки птахів відвідує наш сад. Дані зберігаються як масив цілих чисел, де сьогоднішня кількість стоїть першою.
Визначте today, щоб вона брала масив щоденних кількостей зі стека й повертала сьогоднішню кількість, або f, якщо масив порожній.
{ 2 5 1 } today .
! => 2
{ } today .
! => f
Визначте increment-day-count, щоб вона повертала новий масив, у якому сьогоднішню кількість збільшено на одиницю. Якщо вхідні дані порожні, поверніть { 1 }.
{ 4 0 2 } increment-day-count .
! => { 5 0 2 }
{ } increment-day-count .
! => { 1 }
Визначте has-day-without-birds?, щоб вона повертала t, якщо хоч один день мав нуль птахів, інакше f.
Використайте рекурсію, а не any? чи інші слова вищого порядку для послідовностей.
{ 2 0 4 } has-day-without-birds? . ! => t
{ 3 8 1 5 } has-day-without-birds? . ! => f
Визначте total, щоб вона повертала суму всіх кількостей.
Використайте рекурсію, а не sum.
{ 4 0 9 0 5 } total .
! => 18
Зайнятим днем вважається день, коли птахів пʼять або більше. Визначте busy-days, щоб вона повертала кількість зайнятих днів.
Використайте рекурсію, а не count.
{ 4 5 0 0 6 } busy-days .
! => 2
Зареєструйтеся на Exercism, щоб вивчати й опановувати Factor, а також 47 концепцій163 вправи та справжнє наставництво від людей, і все це безкоштовно.