【问题标题】:what is statically typed in RPython?RPython 中的静态类型是什么?
【发布时间】:2023-03-28 11:15:02
【问题描述】:

经常说RPython(Python 的一个子集)是静态类型的。 (例如Wikipedia。)

最初,我想知道他们如何将其添加到 Python 中,并认为他们可能已经添加了在每个函数的开头添加诸如 assert isinstance(arg1, ...) 之类的语句的要求(但我真的不敢相信)。

然后我查看了一些 RPython 代码,它看起来根本不是静态类型的。在很多情况下,编译器可能会证明函数参数只能是某些类型,但绝对不是在所有情况下。

例如,这是string.split的RPython实现:

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 是静态类型的?或者这实际上是错误的?

【问题讨论】:

标签: python static-typing pypy rpython


【解决方案1】:

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

他们当然会。他们总是使用几乎所有语言。

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

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

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

当然不是。有很多不是静态类型的代码,还有相当多的静态类型的代码,当前的注释器无法证明是静态类型的。但是当遇到这样的代码时,这是一个编译错误,句号。

有几点需要注意:

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

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

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

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

【讨论】:

  • 啊,那个位[静态类型]在整个程序的基础上是我认为这里主要的重要位。因为,正如您所写,函数 def add(a, b): return a + b 不是静态类型的,甚至可以用于几种不同的类型。
  • @Albert:也请查看我的编辑以回应您对 zeekay 回答的评论。您可能已经摆脱了静态类型是清单类型这一古老而流行的误解。
【解决方案2】:

是的,它是静态类型的。在您的示例中,没有任何变量更改类型,这符合 RPython 在这方面的要求。 RPython is not formally defined, and it's restrictions are constantly evolving,但文档仍然是一个不错的起点。阅读一番后,最好的办法是尝试翻译一些代码,你会很快弄清楚你能做什么,不能做什么!

【讨论】:

  • 但是不改变类型和静态类型是不同的。我看到在示例中,变量不会改变它们的类型,但它们不是静态类型的。
  • 在翻译类型推断完成期间,您不必显式定义变量的类型。
  • 那个 URL 似乎不再起作用了。很高兴知道实际的限制是什么。
猜你喜欢
  • 2010-10-25
  • 2014-09-27
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多