• [^] # Re: go 2.0

    Posté par . En réponse au journal Pourquoi la recherche en langages de programmation ?. Évalué à 2.

    Par contre, ce n'est pas du tout évident en lisant tes exemples.

    Essaye de faire le dernier exemple avec un enregistrement, tu verras le problème. ;-)

    type ('t,'u) par = {v : 'u 't};;
    Error: Syntax error

    Il est possible d'encoder la chose avec des enregistrements en utilisant la bibliothèque Higher et la technique dite de défonctionnalisation de Reynolds (transformer un code fonctionnel vers un langage non fonctionnel), mais ça devient aussi tricky que les modules.

    (*
     ce type sert d'encodage pour dire que l'on applique 
     le type paramétrique 't à la variable de type 'a
    *)
    type ('a, 't) app
    module Higher_Kind (T : sig type 'a t end) =
    struct
     (* on a notre type paramétrique *)
     type 'a s = 'a T.t
     (* on le manipule de l'extérieur comme un type non paramétrique *)
     type t
     (* une injection et une projection pour passer de la version
     paramétrique à son encodage non paramétrique *)
     external inj : 'a s -> ('a, t) app = "%identity"
     external proj : ('a, t) app -> 'a s = "%identity"
    end
    module Higher_list = Higher_Kind(struct type 'a t = 'a list end)
    module Higher_option = Higher_Kind(struct type 'a t = 'a option end)
    type ('t, 'u) par = {v : ('u, 't) app}
    let m = {v = Higher_list.inj ["Hello World !"]};;
    val m : (Higher_list.t, string) par = {v = <abstr>}
    let n = {v = Higher_option.inj (Some 1)};;
    val n : (Higher_option.t, int) par = {v = <abstr>}
    M.v = Higher_list.proj m.v && N.v = Higher_option.proj n.v;;
    - : bool = true

    Manipuler les types paramétriques (qui sont des fonctions des types vers les types) comme des types de première classe au niveau des abstractions est ce que l'on appelle communément higher-kinded polymorphism : cela revient à voir le langage des types comme un langage fonctionnel et à lui associer son propre système de type (ou kind) en conséquence.

    Et pourquoi 3 syntaxes différentes pour faire la même chose ou presque ?

    Parce que les 3 ne font pas la même chose : les modules permettent de faire ce que font les deux autres, les objets ont l'héritage et le sous-typage mais pas les enregistrements, tous les modules ne peuvent pas être manipuler correctement en tant que citoyen de première classe (ceux qui ont des types paramétriques justement), et que le compilateur ne leur associe pas la même représentation mémoire en conséquence des différentes possibilités qu'ils offrent.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.