Как делать бесконечные (или действительно глубокие) рекурсии в Stackless Python? - PullRequest
3 голосов
/ 24 марта 2019

Я знаю, что стандартный CPython имеет ограничение на глубину рекурсии, я думаю, он меньше 1000, поэтому приведенный ниже пример кода завершится с ошибкой «максимальная глубина рекурсии превышена».

def rec_add(x):
    if x == 0:
        return x
    else:
        return x + add(x - 1)

print(rec_add(1000))

Я слышал Stackless Pythonподдерживает бесконечную глубину рекурсии, но если я запускаю приведенный выше код со Stackless Python, он все равно сообщает об ошибке «превышена максимальная глубина рекурсии».Я думаю, возможно, мне нужно как-то изменить код, чтобы он мог использовать функцию бесконечной глубины рекурсии в Stackless Python?

Есть идеи, как сделать бесконечные рекурсии в Stackless Python?Спасибо.

Примечание: я знаю, как увеличить предел глубины рекурсии стандартного CPython более 1000, и я знаю, как преобразовать приведенный выше код в простую итерацию, или просто использовать формулу Гаусса для вычисления суммы.не то, что я ищу, и приведенный выше код приведен исключительно в качестве примера.

РЕДАКТИРОВАТЬ: Как я уже говорил в части «Примечание» выше (что, я думаю, никто на самом деле не читает), я знаю, какчтобы увеличить предел рекурсии CPython, и я знаю, как преобразовать пример кода в итерации или просто формулу суммы Гаусса n * (n + 1) / 2, я просто спрашиваю здесь, потому что я услышал одну из замечательных особенностей StacklessPython - это то, что он допускает бесконечные рекурсии, и я не знаю, как я могу включить его для примера кода.

EDIT2: я не уверен, что у меня появилась идея: «Stackless Python поддерживает бесконечные рекурсии»неправильно, но вот некоторые источники, которые говорят (или ссылаются на), что Stackless Python поддерживает бесконечные рекурсии:

Каковы недостатки стекаменьше Python?

https://bitbucket.org/stackless-dev/stackless/issues/96

https://stackless.readthedocs.io/en/3.6-slp/whatsnew/stackless.html

1 Ответ

1 голос
/ 24 марта 2019

После возни я получил следующий код, основанный на официальном примере кода более десяти лет назад здесь

https://bitbucket.org/stackless-dev/stacklessexamples/src/a01959c240e2aeae068e56b86b4c2a84a8d854e0/examples/?at=default

, поэтому я изменил код рекурсивного сложения так, чтобы он выглядел следующим образом

import stackless


def call_wrapper(f, args, kwargs, result_ch):
    result_ch.send(f(*args, **kwargs))


def call(f, *args, **kwargs):
    result_ch = stackless.channel()
    stackless.tasklet(call_wrapper)(f, args, kwargs, result_ch)
    return result_ch.receive()


def rec_add(n):
    if n <= 1:
        return 1
    return n + call(rec_add, n-1)


print(rec_add(1000000))

Он работает с большим числом, например 1 000 000, я думаю, это своего рода косвенная рекурсия, поскольку функция вызывает другую функцию, которая запускает тасклет, который вызывает саму функцию (или что-то в этом роде).

Теперь мне интересно, действительно ли это предполагаемый способ реализации бесконечной рекурсии в Stackless Python, или есть более прямые / прямые способы сделать это?Спасибо.

...