amarao: (Default)
amarao ([personal profile] amarao) wrote2022-07-20 07:16 pm

Crazy python

Функция выглядит как вычислимая примитивно-рекурсивная, но на самом деле невычислимая общерекурсивная!

Доказательство

def foo(i):
    if i < 0 or i > 10:
        return i
    try:
        print(f"{i} - 1")
        return foo(i-1)
    finally:
        print(f"{i} + 1")
        return foo(i+1)

print(foo(5))

На самом деле эта функция - чистое UB в питоне. После долгих лет рассказа о том, что в питоне нет UB.

Вот более интересный генератор последовательностей на той же базе.

def foo(i):
    if i < 0 or i > 10:
        return i
    print(i, end='', sep='')
    try:
        return foo(i-1)
    finally:
        return foo(i+1)

print(foo(5))

Чем не генератор случайных чисел?

juan_gandhi: (Default)

[personal profile] juan_gandhi 2022-07-20 04:52 pm (UTC)(link)

What's ub?

yurikhan: (Default)

[personal profile] yurikhan 2022-07-20 05:22 pm (UTC)(link)

Чё это UB? Language Reference § 8.4 The try statement:

The return value of a function is determined by the last return statement executed. Since the finally clause always executes, a return statement executed in the finally clause will always be the last one executed[.]

Банальная нетерминированная взаимная рекурсия между foo(1) и foo(0), с коротким заходом в foo(-1) на каждом круге.

yurikhan: (Default)

[personal profile] yurikhan 2022-07-20 05:42 pm (UTC)(link)

Ну кек бы условие «базы рекурсии» поменялось — было < 0, стало < 1. Теперь такая же нетерминированная рекурсия между foo(2) и foo(1) с заходом в foo(0) (которого не видно, потому что он возвращает 0 без print’а).

yurikhan: (Default)

[personal profile] yurikhan 2022-07-20 05:46 pm (UTC)(link)

Так, а вот продолжать рекурсию при получении KeyboardInterrupt — это подстава.

yurikhan: (Default)

[personal profile] yurikhan 2022-07-21 07:27 am (UTC)(link)

Это для тех, у кого нет соседней вкладки с htop’ом :P