Estruturas de dados em linguagem de programação com tipos lineares

15

Suponha que estamos lidando com uma linguagem de programação que suporta tipos lineares (os termos do tipo linear podem ser usados ​​no máximo uma vez, por assim dizer). Isso permite tratar alguns efeitos computacionais (como mutação, até mesmo alterar o tipo do operando) de uma maneira problemática para as linguagens, cujos sistemas de tipos operam apenas em "verdades eternas".

Muitas estruturas de dados podem ser caracterizadas com tipos indutivos (listas e árvores são exemplos canônicos). Se adicionarmos tipos indutivos lineares à mistura, também podemos lidar com estruturas de dados mutáveis.

No entanto, não está claro para mim como representar estruturas de dados que exibem compartilhamento e referências cíclicas em uma linguagem de programação com tipos lineares (exemplos de tais estruturas de dados são DAGs e outros gráficos, representados por listas de adjacências ou outra coisa, listas cíclicas). Podemos fazer isso? Se não for possível, de que maneira devemos estender a linguagem para acomodar essas estruturas de dados?

O exemplo mais envolvido que encontrei até agora é uma lista duplamente vinculada. Existem outros exemplos?

Bjørn Kjos-Hanssen
fonte

Respostas:

20

A linearidade não é uma restrição suficiente para definir uma representação com estado única e, portanto, a resposta à sua pergunta depende de como você interpreta a lógica linear em termos de estado. Isso normalmente será refletido em como você deve interpretar o modalidade.!UMA

Se a semântica pretendida das referências disser que todos os ponteiros são valores únicos (ou seja, existe no máximo uma única referência a um objeto), os dags e as estruturas gráficas não são expressáveis, pelo tipo de razão tautológica em que um dag pode conter várias referências a o mesmo objeto. Nesse caso deve ser um cálculo que cria um novo valor do tipo A , desde que você quer mapas δ A : ! A ! A ! Um e ε A : ! A A!UMAUMAδUMA:!UMA!UMA!UMAϵUMA:!UMAUMA .

No entanto, suponha que você queira para representar o compartilhamento . Então, os objectos podem ser com a contagem de referência recolhidos-lixo, com os mapas ô Um : ! A ! A ! Um e ε A : ! A A pode ser realizado como operações que apenas aumentam as contagens de referência. Nesse caso, você não pode usar a linearidade para assumir que é sempre seguro alterar valores, já que há compartilhamento. Mas você pode garantir que toda a alocação de memória seja explícita no seu programa e que não haja ciclos no heap.!UMAδUMA:!UMA!UMA!UMAϵUMA:!UMAUMA

A maioria das implementações práticas de tipos lineares não usa nenhuma dessas duas interpretações. Em vez disso, as referências são vistas como entidades livremente duplicáveis, e o que rastreamos linearmente são de fato recursos . Recursos não são valores de tempo de execução; elas são entidades puramente conceituais, destinadas a representar a permissão para acessar uma referência. A idéia é que você programe em um estilo de passagem de permissão e, mesmo que haja muitas referências ao mesmo objeto, uma leitura ou modificação de um pedaço de estado só poderá ocorrer se você também tiver a capacidade de acessá-lo. E como a capacidade é linear, você sabe que somente você pode alterá-la.

new:α.αc:ι.cap(c)ref(α,c)get:α,c:ι.cumap(c)ref(α,c)αcumap(c)ref(α,c)set:α,c:ι.cumap(c)ref(α,c)αcumap(c)ref(α,c)copy:α,c:ι.ref(α,c)ref(α,c)ref(α,c)

Na API esboçada acima, varia sobre ι , algum domínio de índices em tempo de compilação e α varia sobre tipos. Temos um tipo c a p ( c ), que é uma capacidade indexada por c , e um tipo r e f ( α , c ) , que é um tipo de referência a α acessada por uma capacidade c . Chamar g de e t e s e t em uma referência requer a capacidade C , e ligando n ecιαcumap(c)cref(α,c)αcgetsetc cria uma nova referência e um novo recurso que compartilha um índice comum. No entanto, c o p y ing uma referência não requer acesso a qualquer recurso, para que qualquer pessoa pode copiar uma referência, desde que eles não olhar para ele.neWcopy

Neel Krishnaswami
fonte
Obrigado por uma resposta instigante. Estou interessado, porém, existe uma distinção (técnica) entre alias e compartilhamento? Existem sistemas que podem gradualmente passar de linear (no máximo uma referência) para compartilhado por no máximo n referências para compartilhado de maneira irrestrita?
11
1. Alias ​​e compartilhamento são sinônimos. 2. Sim, interpretações no estilo de capacidade, aumentadas com as permissões fracionárias de Boyland, permitem isso. Veja também o trabalho recente de Pottier sobre cálculo de capacidade para teoria e o trabalho de Aldrich e Bierhof sobre Plural para implementação.
Neel Krishnaswami