Que fragmento da teoria dos tipos dependentes de Martin-Löf pode ser expresso usando tipos genéricos em Java?


8

Eu vim recentemente a perceber que um número de problemas que eu tinha há alguns anos tentando implementar várias teorias matemáticas em Java desceu para o fato de que o sistema de digitação em Java não é suficientemente forte para modelar toda a teoria tipo dependente Martin-Löf .

Antes de Java 5 e genéricos, o único tipo de teoria, você poderia fazer era através de classes e interfaces, que lhe dão tipos arbitrários construídas a partir dos tipos de solo int, double, chare assim por diante usando tipos de produtos e de função. Você também pode criar tipos recursivos como Lists, embora não de maneira uniforme.

Usando genéricos, você pode fazer um pouco mais. Agora você pode definir List<T>como uma função para obtermos tipos de pedidos mais altos.

TypeType

Este não é o fim da história, no entanto. Usando um truque genérico, podemos modelar alguns tipos de produtos dependentes. Por exemplo, podemos definir tipos do formulário usando a sintaxe

T:Typef(T)
public interface f<T extends f<T>>
{
  // We can now refer to T as much as we like
  // inside the class.  T has type f<T>.
}

Como exemplo, podemos modelar a estrutura subjacente básica de um monóide (mas não as condições de associatividade e unitalidade) usando um termo do tipo ( isto é, um conjunto com um elemento de unidade designado e uma operação binária em ). Usando genéricos Java, podemos modelar este tipo:

T:TypeT×(TTT)
TT
public interface MonoidElement<T extends MonoidElement<T>>
{
  public T unit();

  public T mul(T op1, T op2);
}

No entanto, quando tentamos modelar conceitos mais complicados, a teoria dos tipos se decompõe.

Existe uma descrição simples do fragmento do MLTT correspondente aos tipos que podem ser criados no sistema de digitação Java?

Respostas:


12

Existem muitos equívocos aqui. Para começar, o MLTT não possui subtipos; portanto, o Java não será simplesmente um fragmento dele. Não requer tipos dependentes para criar um dos tipos que você forneceu. Um sistema de tipos dependentes não precisa ter um "tipo" de tipos (um universo) em geral (embora o MLTT tenha universos), nem os tipos dependentes para expressar esses tipos. Em um sistema como o cálculo lambda polimórfico / Sistema F , você pode dizer . Java não tem nenhum equivalente ao Type. Um tipo dependente sem um analógico como um tipo polimórfico seria algo como, por exemplo, ouT.T×(TTT)n:NatMatrix(n,n+1)b:Boolif b then Nat else Bool .

Faz mais sentido considerar Java um fragmento de SystemF<: que não é um sistema de tipo dependente. Mesmo assim, é um fragmento bastante fraco. Existe uma variante do sistema F chamada sistema Fωque suporta funções de nível de tipo completo, essencialmente lambda no nível de tipo (não deve ser confundido com lambdas de tipo que relacionam os níveis de valor e tipo e que o Sistema F já possui). Nem Java nem Haskell podem fazer isso. O único nível de tipo "funções" que Haskell (Java) ou Java podem fazer são composições de funções não interpretadas. Não há comportamento computacional no nível do tipo. O Java é ainda mais restrito porque não possui (nem precisa) um sistema de tipos porque não possui tipos de tipos superiores. Ou seja, você não pode ter uma "função" no nível de tipo com "tipo" (ou seja, tipo) por exemplo. É por isso que você não pode criar métodos que operam sobre mônadas arbitrárias em Java. Retornando apenas ao Sistema F, o Sistema F possui tipos arbitrários de classificação.(TypeType)Type profundidade que quiser - você pode usá-lo livremente. Nem Java nem Haskell (sem extensões) suportam isso. Eu acredito que os dois podem capturar indiretamente alguns tipos de classificação mais altos, mas nenhum deles pode expressar o tipo de de Haskell, que requer extensões e é .runSTa.(s.ST s a)a

Portanto, Java é mais expressivo que os tipos de classificação 1, conforme capturado pelo sistema de tipo Hindley-Milner, mas muito menos expressivo que System . Não suporta nenhuma forma de digitação dependente. O Java Featherweight, como introduzido no Featherweight Java: um cálculo básico mínimo para Java e GJ, por Igarashi, Pierce e Wadler, fornece um cálculo simplificado e idealizado, voltado especificamente para Java. Certamente, existe um artigo que compara / reduz diretamente o Featherweight Java para System . O resultado é que o sistema do tipo Java não está nem remotamente próximo do poder do MLTT. Em termos do cubo lambda , ignorando a subtipagem, o Java estaria em algum lugar na borda entreF<:F<:λ, o cálculo lambda de digitação simples e , Sistema F. MLTT (ou especificamente o Cálculo de construções) é , o canto oposto a . Portanto, descrever o Java em termos de MLTT exigiria primeiro ignorar tudo que tornasse o MLTT diferente do System F e, em seguida, ignorar quase tudo que tornasse o System F diferente do System F.λ2λPωλωω


Não tenho certeza do que são os equívocos, mas obrigado - isso praticamente respondeu à minha pergunta.
John Gowers
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.