2011-08-23 17 views
13

Spesso si afferma che RPython (un sottoinsieme di Python) è tipizzato staticamente. (Ad esempio su Wikipedia.)cosa viene tipizzato staticamente in RPython?

Inizialmente, mi chiedevo come avrebbero aggiunto quello a Python e pensavo che avrebbero potuto aggiungere il requisito di aggiungere istruzioni come assert isinstance(arg1, ...) all'inizio di ogni funzione (ma non potevo davvero credere quella).

Poi ho guardato un po 'di codice RPython e non sembra affatto scritto staticamente. In molti casi, potrebbe essere che il compilatore possa provare che un argomento di funzione può essere solo di alcuni tipi ma sicuramente non in tutti i casi.

esempio Questa è l'implementazione di 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 

Nella documentazione PyPy su RPython, si dice: "variabili dovrebbero contenere valori di al massimo un tipo".

Quindi, gli argomenti di funzione contano anche come variabili? O in che senso RPython è tipizzato staticamente? O questo è veramente errato?

+1

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

risposta

14

Quindi, anche gli argomenti di funzione vengono conteggiati come variabili?

Ovviamente lo fanno. Fanno sempre in quasi tutte le lingue.

O in che senso è tipizzato RPython in modo statico? O questo è veramente errato?

La dichiarazione è corretta. RPython non è Python. Bene, è un sottoinsieme di esso e può essere eseguito come codice Python. Ma quando si compila realmente il codice RPython, tanta dinamica viene rimossa da te (anche se solo dopo il tempo di importazione, quindi puoi ancora usare metaclassi, generare codice dalle stringhe, ecc. - usato con grande effetto in alcuni moduli) che il compilatore (che è non il compilatore Python, ma molto diverso dai compilatori tradizionali, vedere la documentazione associata) può infatti decidere che i tipi vengano utilizzati staticamente. Più precisamente, il codice che usa la dinamica lo fa oltre il parser e tutto, ma a un certo punto provoca un errore di tipo.

In molti casi, potrebbe essere che il compilatore possa dimostrare che un argomento di funzione può essere solo di alcuni tipi ma sicuramente non in tutti i casi.

Ovviamente no. C'è un sacco di codice che non è tipizzato staticamente, e un bel po 'di codice tipizzato staticamente che l'annotatore corrente non può dimostrare di essere tipizzato staticamente. Ma quando tale codice è enunciato, è un errore di compilazione, punto.

Ci sono alcuni punti che sono importanti per realizzare:

  • tipi sono desunti, non dichiarato esplicitamente (beh, per la maggior parte, credo che ci sono alcune funzioni che devono affermazioni a aiutare l'annotatore). La tipizzazione statica non significa (come sembra implicare in un commento) che il tipo deve essere scritto (si chiama manifest digit), significa che ogni espressione (che include variabili) ha un singolo tipo che non cambia mai.

  • Tutta quell'analisi avviene su una base di programma completo! Non si può inferire un tipo (non generico) per una funzione def add(a, b): return a + b (gli argomenti potrebbero inti, float, stringhe, liste, ecc.), Ma se la funzione viene chiamata con argomenti interi (ad esempio, valori letterali interi o variabili precedentemente dedotto per contenere numeri interi), è determinato che a e b (e, dal tipo di +, il risultato di add) sono anche numeri interi.

  • Non tutto il codice nel repository PyPy è RPython. Ad esempio, esistono generatori di codice (ad esempio in rlib.parsing) che vengono eseguiti in fase di compilazione e producono codice RPython, ma non sono RPython (spesso con una docstring "NOT_RPYTHON"). Inoltre, ampie parti della libreria standard sono scritte in full Python (principalmente prese direttamente da CPython).

C'è molto materiale molto interessante su come funziona l'intera traduzione e digitazione. Ad esempio, The RPython Toolchain descrive il processo di traduzione in generale, inclusa l'inferenza del tipo e The RPython Typer descrive il sistema di tipi utilizzato.

+0

Ah, quel bit * \ [staticamente digitato \] su una base dell'intero programma * è penso che il principale bit importante qui. Perché, come si scrive anche, la funzione 'def add (a, b): return a + b' non è tipizzata staticamente e può anche essere usata per diversi tipi. – Albert

+0

@Albert: Per favore, sembri la mia modifica in risposta al tuo commento sulla risposta di zeekay. Potresti aver inciampato nel vecchio e popolare malinteso secondo cui la tipizzazione statica è la tipizzazione evidente. – delnan

4

Sì, è staticamente digitato. Nel tuo esempio nessuna delle variabili cambia tipo, che soddisfa i requisiti di RPython a tale riguardo. RPython is not formally defined, and it's restrictions are constantly evolving, ma la documentazione è ancora un buon punto di partenza. Dopo aver letto un po ', la cosa migliore da fare è provare a tradurre un po' di codice, scoprirai cosa puoi e non puoi fare abbastanza velocemente!

+0

Ma non modificare il tipo e digitare staticamente è qualcosa di diverso. Vedo che nell'esempio, le variabili non cambiano il loro tipo ma non sono tipizzate in modo statico. – Albert

+0

Durante l'inferenza del tipo di traduzione, non è necessario definire esplicitamente il tipo di variabili. – zeekay

+0

L'URL sembra non funzionare più. Sarebbe bello sapere quali sono le restrizioni attuali. – Dexter

Problemi correlati