2011-08-23 291 views
13

经常声明,RPython(Python的一个子集)是静态类型的。 (例如,在Wikipedia。)在RPython中静态类型是什么?

起初,我不知道他们会如何添加到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是静态类型的?或者这实际上是错误的?

+1

http://codespeak.net/pypy/dist/pypy/doc/translation.html –

回答

14

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

当然是的。他们总是用几乎所有的语言来做。

或者在什么意义上是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描述了所使用的类型系统。

+0

啊,这个位* \ [静态类型]在整个程序的基础上*我认为这里的主要重点。因为,正如你所写,函数def add(a,b):return a + b'不是静态类型的,甚至可以用于几种不同的类型。 – Albert

+0

@阿尔伯特:请看看我的编辑,以回应您对zeekay答案的评论。您可能已经意识到静态类型是明显输入的老式和流行的误解。 – delnan

4

是的,它是静态类型。在你的例子中,没有任何变量改变类型,这符合RPython在这方面的要求。 RPython is not formally defined, and it's restrictions are constantly evolving,但文档仍然是一个很好的开始。读完一下之后,最好的办法是试着翻译一些代码,你会发现你可以做什么,不能做得很快!

+0

但是不改变类型和静态类型是不同的。我在例子中看到,变量不会改变它们的类型,但它们不是静态类型的。 – Albert

+0

翻译类型推断完成后,您不必显式定义变量的类型。 – zeekay

+0

该URL似乎不再适用。很高兴知道实际限制是什么。 – Dexter