2011-08-23 35 views
13

A menudo se afirma que RPython (un subconjunto de Python) está tipado estáticamente. (Por ejemplo, Wikipedia.)¿Qué está escrito estáticamente en RPython?

Inicialmente, me pregunté cómo agregarían eso a Python y pensaron que podrían haber agregado el requisito de agregar declaraciones como assert isinstance(arg1, ...) al comienzo de cada función (pero realmente no podía creer ese).

Luego miré un código RPython y realmente no se ve estático en absoluto. En muchos casos, es posible que el compilador pueda probar que un argumento de función solo puede ser de ciertos tipos, pero definitivamente no en todos los casos.

por ejemplo, esta es la implementación de 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 

En la documentación sobre PyPy RPython, se dice: "variables deben contener valores de como máximo un tipo".

Entonces, ¿los argumentos de función también cuentan como variables? ¿O en qué sentido está RPython estáticamente tipado? ¿O es esto realmente mal dicho?

+1

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

Respuesta

14

Entonces, ¿los argumentos de función también cuentan como variables?

Por supuesto que sí. Siempre lo hacen en casi todos los idiomas.

¿O en qué sentido está RPython estáticamente tipado? ¿O es esto realmente mal dicho?

La declaración es correcta. RPython no es Python. Bueno, es un subconjunto y se puede ejecutar como código Python. Pero cuando realmente compila el código RPython, se le quita tanto dinamismo (aunque solo después del tiempo de importación, por lo que todavía puede usar metaclases, generar código a partir de cadenas, etc., que el compilador usó con gran efecto) que es no el compilador de Python, pero muy diferente de los compiladores tradicionales; vea la documentación asociada) puede decidir los tipos que se usan estáticamente. Más exactamente, el código que usa dinámica hace que pase el analizador y todo, pero resulta en un error de tipo en algún momento.

En muchos casos, es posible que el compilador pueda probar que un argumento de función solo puede ser de ciertos tipos, pero definitivamente no en todos los casos.

Por supuesto que no. Hay un montón de código que no está tipado estáticamente, y un código bastante estático que el anotador actual no puede demostrar que está tipado estáticamente. Pero cuando ese código se enuncia, es un error de compilación, punto.

Hay algunos puntos que son importantes para hacer realidad:

  • Los tipos son inferidos, no se indica explícitamente (bueno, en su mayor parte, yo creo que hay algunas funciones que necesitan las afirmaciones de ayuda al anotador). La tipificación estática no significa (como parece implicar en un comentario) que el tipo debe escribirse (se denomina tipado manifiesto), significa que cada expresión (que incluye variables) tiene un único tipo que nunca cambia.

  • ¡Todo ese análisis ocurre en un programa completo! No se puede inferir un tipo (no genérico) para una función def add(a, b): return a + b (los argumentos pueden ser ints, floats, strings, listas, etc.), pero si la función se llama con argumentos enteros (por ejemplo, literales enteros o variables que fueron previamente inferido que contiene enteros), se determina que a y b (y, por el tipo de +, el resultado de add) también son enteros.

  • No todos los códigos en el repositorio PyPy son RPython. Por ejemplo, hay generadores de código (por ejemplo, en rlib.parsing) que se ejecutan en tiempo de compilación y producen código RPython, pero no son RPython (con frecuencia con una docstring "NOT_RPYTHON", por cierto). Además, grandes partes de la biblioteca estándar están escritas en Python completo (la mayoría tomadas directamente de CPython).

Hay un montón de material muy interesante sobre cómo funciona realmente la traducción y el tipado. Por ejemplo, The RPython Toolchain describe el proceso de traducción en general, incluida la inferencia de tipo, y The RPython Typer describe el tipo de sistema (s) utilizado (s).

+0

Ah, ese bit * \ [estáticamente estátificado \] sobre una base de programa completo * creo que es el tema principal aquí. Porque, como también escribes, la función 'def add (a, b): return a + b' no está tipada estáticamente e incluso puede usarse para varios tipos diferentes. – Albert

+0

@Albert: Por favor, parezca mi edición en respuesta a su comentario sobre la respuesta de Zeekay. Es posible que haya tropezado con el concepto erróneo, antiguo y popular, de que el tipado estático es tipado manifiesto. – delnan

4

Sí, está estáticamente tipado. En su ejemplo, ninguna de las variables cambia de tipo, lo que cumple con el requisito de RPython en ese sentido. RPython is not formally defined, and it's restrictions are constantly evolving, pero la documentación sigue siendo un buen lugar para comenzar. Después de leer un poco, lo mejor que puede hacer es tratar de traducir algún código, ¡descubrirá lo que puede o no puede hacer bastante rápido!

+0

Pero no cambiar el tipo y estáticamente tipado es algo diferente. Veo que en el ejemplo, las variables no cambian su tipo, pero no están tipadas estáticamente. – Albert

+0

Durante la inferencia de tipo de traducción realizada, no es necesario definir explícitamente el tipo de variables. – zeekay

+0

Esa URL ya no parece funcionar. Sería genial saber cuáles son las restricciones reales. – Dexter

Cuestiones relacionadas