Linearität ist keine ausreichende Einschränkung, um eine eindeutige zustandsbezogene Darstellung festzulegen. Die Antwort auf Ihre Frage hängt daher davon ab, wie Sie die lineare Logik als Zustand interpretieren. Dies wird sich in der Regel darin widerspiegeln, wie Sie das interpretieren müssen Modalität.! EIN
Wenn Ihre beabsichtigte Semantik von Referenzen besagt, dass alle Zeiger eindeutige Werte sind (dh es gibt höchstens eine einzige Referenz auf ein Objekt), sind Tags und Diagrammstrukturen aus dem tautologischen Grund, auf den ein Tag möglicherweise mehrere Referenzen enthält, nicht ausdrückbar das gleiche Objekt. In diesem Fall muss eine sein , die Berechnung , die einen neuen Wert vom Typ erstellt A , da Sie Karten möchten δ A : ! Ein ⊸ ! Ein ⊗ ! A und .! EINEINδEIN: ! Ein ⊸ ! Ein ⊗ ! EINϵEIN: ! A ⊸ A
Nehmen Sie jedoch an, dass Sie möchten, dass das Teilen darstellt . Dann können Objekte mit Referenzzählung mit den Maps und als Operationen realisiert werden, die nur die Referenzzählung erhöhen. In diesem Fall können Sie mit der Linearität nicht davon ausgehen, dass das Mutieren von Werten immer sicher ist, da es gemeinsame Nutzung gibt. Sie können jedoch sicherstellen, dass die gesamte Speicherzuordnung in Ihrem Programm explizit angegeben ist und dass sich keine Zyklen im Heap befinden.δ A : ! Ein ⊸ ! Ein ⊗ ! A ε A : ! A ⊸ A! EINδEIN: ! Ein ⊸ ! Ein ⊗ ! EINϵEIN: ! A ⊸ A
Die meisten praktischen Implementierungen linearer Typen verwenden keine dieser beiden Interpretationen. Stattdessen werden Referenzen als frei duplizierbare Entitäten betrachtet, und was wir linear verfolgen, sind tatsächlich Funktionen . Funktionen sind keine Laufzeitwerte. Es handelt sich um rein konzeptionelle Einheiten, die die Erlaubnis zum Zugriff auf eine Referenz darstellen sollen. Die Idee ist, dass Sie in einem Stil programmieren, bei dem Berechtigungen weitergegeben werden. Selbst wenn viele Verweise auf dasselbe Objekt vorhanden sind, kann ein Status nur dann gelesen oder geändert werden, wenn Sie auch die Möglichkeit haben, darauf zuzugreifen. Und da die Fähigkeit linear ist, wissen Sie, dass nur Sie sie ändern können.
n e wg e ts e tc o p y::::∀ α .& agr; ⊸ ∃ c : ι . c a p ( c ) ⊗ r e f( α , c )∀ & agr; , c : ι .c a p (c)⊗ r e f( Α , c ) ⊸ α ⊗ c a p ( c ) ⊗ R e f( α , c )∀ & agr; , c : ι .c a p (c)⊗ r e f( Α , c ) ⊗ α ⊸ c a p ( c ) ⊗ R e f( α , c )∀ & agr; , c : ι .r e f( Α , c ) ⊸ r e f( Α , c ) ⊗ R e f( α , c )
In der oben skizzierten API liegt über , einem Bereich von Indizes zur Kompilierungszeit, und liegt über Typen. Wir haben einen Typ der eine durch indizierte Fähigkeit ist , und einen Typ , der eine Art von Verweisen auf auf die eine Fähigkeit . Das Aufrufen von und für eine Referenz erfordert die Funktion , und das Aufrufen von erstellt eine neue Referenz und eine neue Funktion, die einen gemeinsamen Index verwendet. Allerdingsι α c a p ( c ) c R e f ( α , c ) α c g e t s e t c n e w c o p ycιαc a p (c)cr e f( α , c )αcg e ts e tcn e wc o p y-um eine Referenz zu erstellen, ist kein Zugriff auf eine Funktion erforderlich, sodass jeder eine Referenz kopieren kann, solange er nicht in sie hineinschaut.