В ленивых языках программирования у вас может быть рекурсия, которая не определяет конечную точку. Результатом может быть бесконечная структура данных, но это нормально, если вы не пытаетесь использовать все это. Например, общий способ определения всего ряда Фибоначчи в Haskell заключается в следующем:
fibS = 1:1: zipWith (+) fibS (tail fibS)
Это переводится на следующий английский: ряд Фибоначчи равен 1, затем 1, за которым следует ряд, который является поэлементной суммой ряда Фибоначчи и ряда Фибоначчи без первого элемента.
Это звучит как рекурсивное определение, а не как рекурсивный вызов функции, но в Haskell нет большого различия - выше просто «нулевая функция» (та, которая не принимает аргументов).
Обычно, чтобы использовать это, вы просто использовали бы первые N элементов fibS. Фактически вы можете использовать все это (например, распечатать все), если вы довольны тем, что ваша программа работает вечно: -)
Для более полезного примера использования «всего» бесконечной рекурсии у веб-сервера может быть «основной цикл», который выполняется навсегда, определенный с помощью рекурсивной функции, которая не завершается.
РЕДАКТИРОВАТЬ: Эти принципы, безусловно, могут применяться к другим языкам, если присутствует какой-то элемент «лени». Вот приведенная выше реализация fibS, портированной на Python с использованием генераторов:
def zipWith(func, iter1, iter2):
while True:
yield func(iter1.next(), iter2.next())
def tail(iter):
iter.next()
for x in iter:
yield x
def fibS():
yield 1
yield 1
for x in zipWith(lambda x,y: x + y, fibS(), tail(fibS())):
yield x
# Test it by printing out the first n elements.
def take(n, iter):
while n > 0:
yield iter.next()
n = n - 1
print list(take(10, fibS()))
Не ожидайте, что он будет таким же эффективным, как версия на Haskell! Вы можете сделать это более эффективным, используя некоторые хаки и глобальные объекты. Но обратите внимание на отсутствие явных условий расторжения.