Possono esserci tipi di valore nelle lingue dinamiche? [chiuso]

0

Un tipo di valore è uno le cui istanze sono a loro volta salvate in variabili. Un tipo di riferimento è un tipo le cui istanze vengono salvate da qualche parte e le variabili contengono solo gli indirizzi delle istanze.

Alcune lingue, come Java, hanno entrambi i tipi. Ad esempio String è un tipo di riferimento e int è un tipo di valore.

public static void main(String[] args) {
    int i; // allocates 4 bytes on the stack, to store an actual integer value
    String s; // allocates 8 bytes on the stack (on 64 bit systems) to store an address
}

Questo è possibile in lingue tipizzate staticamente, perché il tipo di i non cambierà; quindi dopo aver assegnato 4 byte per questo, possiamo inserire qualsiasi valore intero.

Tuttavia, cosa accadrebbe se il tipo di i fosse dinamico? Ad esempio in Python, è possibile:

def demonstrate():
    i = 20
    name = 'george'
    if input() == 'Make a string':
        i = 'hello'
    print('i is ' + i)

Tutti i tipi di Python sono tipi di riferimento. Tuttavia supponiamo che int di Python fosse un tipo di valore (e str ancora un tipo di riferimento) e come risultato proveremmo a mettere effettivamente il numero 20 in i . Nello stack dopo i , inseriamo un riferimento di 8 byte a 'george' .

Dopodiché, potremmo voler cambiare il valore di i in 'hello' . Ciò significa riallocarne lo spazio nello stack, anziché la stanza precedentemente allocata per il numero 20 .

La mia domanda è: è possibile (o pratico)? Esistono linguaggi dinamici che supportano tipi di valore? Se sì, come?

    
posta Aviv Cohn 24.09.2015 - 22:51
fonte

2 risposte

3

Sì, è possibile e in effetti è comune "annullare la pubblicazione" dei valori di tipi comuni per motivi di prestazioni, in genere con una sorta di "taggatura" per indicare se un valore è in scatola o non in scatola.

La rappresentazione più semplice possibile è con una parola per il tag type e una parola per il valore o il puntatore, in base al tag.

enum Type { INTEGER, REFERENCE };

struct Value {
  Type type;
  union {
    uint64_t as_integer;
    Object *as_reference;
  } data;
};

Ma possiamo fare di meglio. Ad esempio, le allocazioni dell'heap in molti sistemi sono allineate ai limiti di 8 byte, il che significa che i 3 bit inferiori di qualsiasi puntatore ( (uintptr_t)p & 7 ) sono garantiti come 0. Come tali, possiamo usare questi bit per memorizzare il tag, e quindi ottenere rappresentazioni unboxed di tipi comuni con una sola parola. Ecco un semplice progetto di questo tipo, per un sistema a 32 bit:

(x & 7) == 0 => (x & ~7) is a pointer
(x & 7) == 1 => (x >> 3) is an integer

(Questa rappresentazione è usata da OCaml, un linguaggio tipizzato staticamente, per determinare quali valori sono riferimenti che devono essere tracciati dal garbage collector.)

Potremmo aggiungere fino a 6 rappresentazioni aggiuntive a questo, per i booleani e altri tipi comuni che potremmo desiderare di unbox, e un ulteriore 8 se avessimo un allocatore di memoria che garantisse l'allineamento di 16 byte.

In magia del puntatore per rappresentazioni di valori dinamici efficienti , Nikita Popov descrive un sistema per incorporare interi, booleani e numeri in virgola mobile in una singola parola a 64 bit facendo ipotesi sulla rappresentazione di float ( IEEE-754 ) e gli spazi degli indirizzi. Una rappresentazione simile è stata utilizzata nel motore JavaScript JägerMonkey di Mozilla.

    
risposta data 24.09.2015 - 23:15
fonte
0

All Python types are reference types.

Questo è sbagliato. (Bene, tipo di.)

However suppose Python's int were a value type

Non c'è bisogno di supporre. è un tipo di valore. (Bene, tipo di.)

Per essere precisi, non è possibile stabilire se si tratta di un tipo di valore o di un tipo di riferimento. In Python, int s è immutabile e per i tipi immutabili è impossibile stabilire se si tratta di tipi di valore o di riferimento, quindi int s potrebbe essere o non conoscere la differenza. Sono, tuttavia, implementati come tipi di valore in tutte le implementazioni Python che conosco, e il linguaggio nel documento / specifiche Python suggerisce strongmente di implementarli come tipi di valore.

    
risposta data 25.09.2015 - 01:17
fonte

Leggi altre domande sui tag