Je commence à plonger dans une programmation typée dépendante et j'ai découvert que les langages Agda et Idris sont les plus proches de Haskell, alors j'ai commencé par là.
Ma question est: quelles sont les principales différences entre eux? Les systèmes de types sont-ils également expresifs dans les deux? Ce serait formidable d'avoir un comparatif complet et une discussion sur les avantages.
J'ai pu en repérer:
Edit : il y a d'autres réponses dans la page Reddit de cette question: http://www.reddit.com/r/dependent_types/comments/q8n2q/agda_vs_idris /
Je ne suis peut-être pas la meilleure personne pour répondre à cette question, car après avoir implémenté Idris, je suis probablement un peu partisan! Le FAQ - http://docs.idris-lang.org/en/latest/faq/faq.html - a quelque chose à dire là-dessus, mais à développer un peu:
Idris a été conçu dès le départ pour prendre en charge la programmation à usage général avant la démonstration du théorème, et en tant que tel, il dispose de fonctionnalités de haut niveau telles que les classes de type, la notation do, les crochets idiomatiques, les listes de compréhension, la surcharge, etc. Idris met la programmation de haut niveau avant la preuve interactive, bien que parce qu'Idris est construit sur un élaborateur basé sur la tactique, il existe une interface avec un prouveur de théorème interactif basé sur la tactique (un peu comme Coq, mais pas aussi avancé, du moins pas encore).
Une autre chose que Idris vise à bien prendre en charge est la mise en œuvre de DSL intégré. Avec Haskell, vous pouvez obtenir un long chemin avec la notation do, et vous pouvez aussi avec Idris, mais vous pouvez également lier d'autres constructions telles que l'application et la liaison de variables si vous en avez besoin. Vous pouvez trouver plus de détails à ce sujet dans le tutoriel, ou tous les détails dans cet article: http://www.cs.st-andrews.ac.uk/~eb/drafts/dsl-idris.pdf =
Une autre différence réside dans la compilation. Agda passe principalement par Haskell, Idris par C. Il existe un backend expérimental pour Agda qui utilise le même backend que Idris, par C. Je ne sais pas comment il est bien entretenu. Un objectif principal d'Idris sera toujours de générer du code efficace - nous pouvons faire beaucoup mieux que nous le faisons actuellement, mais nous y travaillons.
Les systèmes de types d'Agda et d'Idris sont assez similaires à bien des égards importants. Je pense que la principale différence réside dans la gestion des univers. Agda a un polymorphisme d'univers, Idris a cumulativité (et vous pouvez avoir Set : Set
dans les deux cas si vous trouvez cela trop restrictif et que cela ne vous dérange pas que vos preuves puissent être erronées).
Une autre différence entre Idris et Agda est que l'égalité propositionnelle d'Idris est hétérogène, tandis que celle d'Agda est homogène.
En d'autres termes, la définition putative de l'égalité dans Idris serait:
data (=) : {a, b : Type} -> a -> b -> Type where
refl : x = x
à Agda, c'est
data _≡_ {l} {A : Set l} (x : A) : A → Set a where
refl : x ≡ x
Le l dans la définition d'Agda peut être ignoré, car il a à voir avec le polymorphisme de l'univers qu'Edwin mentionne dans sa réponse.
La différence importante est que le type d'égalité dans Agda prend deux éléments de A comme arguments, tandis que dans Idris il peut prendre deux valeurs avec potentiellement différents types.
En d'autres termes, dans Idris, on peut affirmer que deux choses de types différents sont égales (même si cela finit par être une revendication non démontrable), tandis que dans Agda, la déclaration même est un non-sens.
Cela a des conséquences importantes et étendues pour la théorie des types, en particulier en ce qui concerne la faisabilité de travailler avec la théorie des types d'homotopie. Pour cela, l'égalité hétérogène ne fonctionnera tout simplement pas car elle nécessite un axiome qui n'est pas cohérent avec HoTT. D'un autre côté, il est possible d'énoncer des théorèmes utiles avec une égalité hétérogène qui ne peuvent pas être énoncés simplement avec une égalité homogène.
L'exemple le plus simple est peut-être l'associativité de la concaténation vectorielle. Étant donné des listes indexées en longueur appelées vecteurs définis ainsi:
data Vect : Nat -> Type -> Type where
Nil : Vect 0 a
(::) : a -> Vect n a -> Vect (S n) a
et concaténation avec le type suivant:
(++) : Vect n a -> Vect m a -> Vect (n + m) a
nous pourrions vouloir prouver que:
concatAssoc : (xs : Vect n a) -> (ys : Vect m a) -> (zs : Vect o a) ->
xs ++ (ys ++ zs) = (xs ++ ys) ++ zs
Cette instruction est absurde sous l'égalité homogène, car le côté gauche de l'égalité a le type Vect (n + (m + o)) a
et le côté droit a le type Vect ((n + m) + o) a
. C'est une déclaration parfaitement sensée avec une égalité hétérogène.