14

人们经常说RPython(Python 的一个子集)是静态类型的。(例如在维基百科上。)

最初,我想知道他们如何将其添加到 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's already < 0, it stays < 0

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

在有关 RPython 的 PyPy 文档中,它说:“变量应该包含最多一种类型的值”。

那么,函数参数也算作变量吗?或者在什么意义上 RPython 是静态类型的?或者这实际上是错误的?

4

2 回答 2

15

那么,函数参数也算作变量吗?

他们当然会。他们总是用几乎每一种语言做。

或者在什么意义上 RPython 是静态类型的?或者这实际上是错误的?

陈述是正确的。RPython 不是 Python。好吧,它是它的一个子集,可以作为 Python 代码运行。但是当你实际编译 RPython 代码时,你会失去很多动态性(尽管只是在导入时间之后,所以你仍然可以使用元类,从字符串生成代码等 - 在某些模块中效果很好)编译器(它不是Python 编译器,但与传统编译器有很大不同;请参阅相关文档)确实可以决定静态使用类型。更准确地说,使用动态性的代码可以通过解析器和所有内容,但在某些时候会导致类型错误。

在许多情况下,编译器可能可以证明函数参数只能是某些类型,但绝对不是在所有情况下。

当然不是。有很多不是静态类型的代码,还有相当多的静态类型代码,当前的注释器无法证明是静态类型的。但是当这样的代码被引用时,它是一个编译错误,期间。

有几点很重要,需要意识到:

  • 类型是推断出来的,而不是明确说明的(嗯,在大多数情况下;我相信有一些函数需要断言来帮助注释器)。静态类型并不(正如您在评论中暗示的那样)意味着必须写出类型(这称为清单类型),它意味着每个表达式(包括变量)都有一个永远不会改变的类型。

  • 所有这些分析都是在整个程序的基础上进行的!无法推断函数的(非泛型)类型def add(a, b): return a + b(参数可能是整数、浮点数、字符串、列表等),但是如果使用整数参数调用函数(例如,之前推断的整数文字或变量包含整数),确定ab(并且,根据 的类型+, 的结果add)也是整数。

  • 并非 PyPy 存储库中的所有代码都是 RPython。例如,有一些代码生成器(例如 in rlib.parsing)在编译时运行并生成 RPython 代码,但不是 RPython("NOT_RPYTHON"顺便说一下,通常带有文档字符串)。此外,标准库的大部分是用完整的 Python 编写的(大部分直接取自 CPython)。

关于整个翻译和打字的实际​​工作方式,有很多非常有趣的材料。例如,RPython Toolchain描述了一般的翻译过程,包括类型推断,RPython Typer描述了使用的类型系统。

于 2011-08-23T14:06:55.547 回答
4

Yes, it is statically typed. In your example none of the variables change type, which meets RPython's requirement in that regard. RPython is not formally defined, and it's restrictions are constantly evolving, but the documentation is still a good place to start. After reading up a bit, the best thing to do is to try and translate some code, you'll figure out what you can and can't do pretty quick!

于 2011-08-23T14:03:30.020 回答