Подтвердить что ты не робот

Что статически типизировано в RPython?

Часто говорится, что RPython (подмножество Python) статически типизировано. (Например, на Wikipedia.)

Вначале я задавался вопросом, как они добавят это в Python, и подумал, что они могли добавить требование добавить такие выражения, как assert isinstance(arg1, ...) в начале каждой функции (но я не мог поверить в это).

Затем я посмотрел на некоторый код RPython, и на самом деле он не выглядит статически типизированным. Во многих случаях может случиться так, что компилятор может доказать, что аргумент функции может быть только определенного типа, но определенно не во всех случаях.

Например, это реализация RPython string.split:

def split(value, by, maxsplit=-1):
    bylen = len(by)
    if bylen == 0:
        raise ValueError("empty separator")

    res = []
    start = 0
    while maxsplit != 0:
        next = value.find(by, start)
        if next < 0:
            break
        res.append(value[start:next])
        start = next + bylen
        maxsplit -= 1   # NB. if it already < 0, it stays < 0

    res.append(value[start:len(value)])
    return res

В документации PyPy о RPython говорится: "переменные должны содержать значения не более одного типа".

Итак, аргументы функции также считаются переменными? Или в каком смысле статично типизирован RPython? Или это фактически неверно?

4b9b3361

Ответ 1

Итак, аргументы функции также считаются переменными?

Конечно, да. Они всегда делают практически на каждом языке.

Или в каком смысле ставится типизированный тип RPython? Или это фактически неверно?

Утверждение верно. RPython не является Python. Ну, это его подмножество и может быть запущено как код Python. Но когда вы на самом деле компилируете код RPython, так много динамичности отнимается у вас (хотя и только после времени импорта, поэтому вы все равно можете использовать метаклассы, генерировать код из строк и т.д., Которые были использованы в некоторых модулях), что компилятор ( который не компилятор Python, но значительно отличается от традиционных компиляторов, см. соответствующую документацию), действительно может решить, что типы используются статически. Точнее, код, который использует динамичность, заставляет его пройти парсер и все, но в какой-то момент приводит к ошибке типа.

Во многих случаях может быть, что компилятор может доказать, что аргумент функции может быть только определенного типа, но определенно не во всех случаях.

Конечно нет. Там много кода, который не статически типизирован, и довольно некоторый статически типизированный код, текущий аннотатор не может быть статически типизирован. Но когда такой код изменяется, это ошибки компиляции, период.

Есть несколько моментов, которые важны для понимания:

  • Типы выводятся, не указаны явно (ну, по большей части, я считаю, что есть несколько функций, которые требуют утверждений, чтобы помочь аннотатору). Статическая типизация не означает (как вы, кажется, подразумеваете в комментарии), означает, что тип должен быть выписан (это называется отображением манифеста), это означает, что каждое выражение (включающее переменные) имеет один тип, который никогда не изменяется.

  • Все эти анализы происходят на основе всей программы! Нельзя вывести (не общий) тип для функции def add(a, b): return a + b (аргументы могут быть ints, floats, строки, списки и т.д.), Но если функция вызывается с целыми аргументами (например, целочисленными литералами или переменными, которые ранее предполагалось содержать целые числа), определяется, что a и b (и по типу + результат add) также являются целыми числами.

  • Не весь код в репозитории PyPy - это RPython. Например, есть генераторы кода (например, в rlib.parsing), которые выполняются во время компиляции и производят код RPython, но не являются RPython (часто с "NOT_RPYTHON" docstring, кстати). Кроме того, большие части стандартной библиотеки написаны в полном Python (в основном, взяты прямо из CPython).

Там очень много интересного материала о том, как работает весь перевод и ввод текста. Например, Инструмент RPython Toolchain описывает процесс перевода в целом, включая вывод типа, и RPython Typer описывает используемую систему типов.

Ответ 2

Да, он статически типизирован. В вашем примере ни один из переменных не меняет тип, который соответствует требованиям RPython в этом отношении. RPython официально не определен, и ограничения постоянно меняются, но документация по-прежнему является хорошим местом для начала. Немного покончив, лучше всего попробовать и перевести код, вы поймете, что можете и не можете сделать довольно быстро!