• [^] # Re: Typage structurel

    Posté par . En réponse au journal C++ Hell/Heaven et les concepts. Évalué à 3.

    La commutativité et l'associativité sont des points super importants en calcul sur des gros volumes. Que ce soit en C++ ou en n'importe quoi.

    • Associativité: tu peux séparer en morceaux indépendants
    • Commutativité: l'ordre n'est pas important, ainsi tu peux traiter les morceaux quand ils arrivent et ne pas dépendre de la latence réseau par exemple.

    Ce n'est pas moi qui dirait le contraire : ces propriétés permettent d'effectuer les calculs dans n'importe quel ordre, i.e. quelque soit la permutation effectuée sur la séquence d'opérations on aboutit toujours au même résultat. Ainsi, on est moins tributaire du temps d'accès aux données (peu importe l'ordre dans lesquelles elles arrivent) que ce soit du à de la latence réseau, ou à des échanges répétés entre le cache et la ram. ;-)

    ;)

    Il y a une série d'articles de blogs (compilé en un livre) sur le thème théorie des catégories pour les programmeurs. L'auteur y donne des illustrations de code en Haskell et C++ : c'est dingue à quel point la syntaxe du C++ est tordue et peu « parlante ». Si l'on prend la notion élémentaire de monoïde (cf chapitre 3), en Haskell cela se définit ainsi :

    class Monoid m where
     mempty :: m
     mappend :: m -> m -> m

    autrement dit un monoïde sur un type m est la donnée d'un élément neutre et d'une opération associative (important l'associativité, même si le contrat est implicite entre les programmeurs ;-). Là où en C++, avec les concepts, on se retrouve à le définir ainsi :

    template<class T>
     T mempty = delete;
    template<class T>
     T mappend(T, T) = delete;
    template<class M>
     concept bool Monoid = requires (M m) {
     { mempty<M> } -> M;
     { mappend(m, m); } -> M;
     };

    Non, mais what the fuck !? :-o

    Par comparaison, en ML, c'est proche du Haskell mais plus conforme à la définition formelle des mathématiciens :

    module type Mondoid = struct
     type t
     val mappend : t -> t -> t
     val mempty : t
    end

    c'est-à-dire la donnée conjointe d'un type (ou concept, ou ensemble...), d'une loi de composition interne associative et d'un élément neutre pour cette loi. La différence avec Haskell étant que le type fait partie du dictionnaire, là où en Haskell le type support du monoïde paramétrise le dictionnaire qui n'a que deux éléménts. C'est similaire à ce type produit :

    type 'm monoid = {
     mempty : 'm ;
     mappend : 'm -> 'm -> 'm
    }

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