La linearità non è un vincolo sufficiente per definire una rappresentazione stateful unica, quindi la risposta alla tua domanda dipende da come interpreti la logica lineare in termini di stato. Questo si rifletterà in genere nel modo in cui devi interpretare !A modalità.
Se la semantica di riferimenti prevista indica che tutti i puntatori sono valori univoci (ovvero esiste al massimo un singolo riferimento a un oggetto), le strutture dei grafici e dei punti non sono espressibili, per il tipo di motivo tautologico che un dag può contenere più riferimenti a lo stesso oggetto. In questo caso deve essere un calcolo che crea un nuovo valore di tipo A , dal momento che si desidera Maps E .!AAε A : ! A ⊸ AδA:!A⊸!A⊗!AϵA:!A⊸A
Tuttavia, supponiamo che tu voglia per rappresentare la condivisione . Quindi, gli oggetti possono essere con il conteggio dei riferimenti, con le mappe e possono essere realizzate come operazioni che contano solo i riferimenti. In questo caso, non è possibile utilizzare la linearità per assumere che sia sempre sicuro mutare valori, poiché esiste la condivisione. Ma puoi assicurarti che tutta l'allocazione di memoria sia esplicita nel tuo programma e che non ci siano cicli nell'heap.δ A : ! A ⊸ ! A ⊗ ! A ε A : ! A ⊸ A!AδA:!A⊸!A⊗!AϵA:!A⊸A
Le implementazioni più pratiche di tipi lineari non usano nessuna di queste due interpretazioni. Invece, i riferimenti sono visti come entità liberamente duplicabili e ciò che tracciamo linearmente sono in realtà capacità . Le capacità non sono valori di runtime; sono entità puramente concettuali che intendono rappresentare l'autorizzazione ad accedere a un riferimento. L'idea è che si programma in uno stile di passaggio delle autorizzazioni, e quindi anche se ci sono molti riferimenti allo stesso oggetto, una lettura o modifica di un pezzo di stato può avvenire solo se si ha anche la possibilità di accedervi. E poiché la capacità è lineare, sai che solo tu puoi cambiarla.
n e wg e tsetcopy::::∀α.α⊸∃c:ι.cap(c)⊗ref(α,c)∀α,c:ι.cap(c)⊗ref(α,c)⊸α⊗cap(c)⊗ref(α,c)∀α,c:ι.cap(c)⊗ref(α,c)⊗α⊸cap(c)⊗ref(α,c)∀α,c:ι.ref(α,c)⊸ref(α,c)⊗ref(α,c)
Nell'API di cui sopra, va su , alcuni domini di indici in fase di compilazione e su tipi. Abbiamo un tipo che è una capacità indicizzata da , e un tipo , che è un tipo di riferimenti a accede una capacità . Chiamare e su un riferimento richiede la capacità , e chiamare crea un nuovo riferimento e una nuova capacità che condivide un indice comune. Tuttavia,cιαcap(c)cref(α,c)αcgetsetcnewcopy-ing un riferimento non richiede l'accesso a nessuna funzionalità, quindi chiunque può copiare un riferimento purché non guardi al suo interno.