Ça l'est : tu veux faire du polymorphisme ad-hoc; mais je ne vois pas où on a besoin de typage dynamique pour cela.
L'idée du polymorphisme ad-hoc est d'avoir des fonctions qui ont le même nom (ici Greeting) mais qui opère sur différents types et selon des logiques différentes (à la différence du polymorphisme paramétrique). Ensuite à l'usage (comme dans ta fonction foo) la fonction effectivement utilisée est choisie en fonction du type du paramètre (type base dispatch). C'est exactement ce que font les type classes de Haskell et les traits du Rust. Cette manière de faire est bien plus intelligente (j'ai envie de dire moins inepte) que l'approche de l'orienté objet. En OCaml on passe par des modules et foncteurs pour faire cela (avec une perte de l'implicite) et il me semble (mais là je suis moins sûr) que les template du C++ peuvent servir à cela.
Pour présenter grossièrement l'idée, il s'agit d'associer à un type un dictionnaire de fonctions pour opérer dessus, c'est l'interface contre laquelle on veut programmer de manière générique. En fonction du type du paramètre, le compilateur choisira le dictionnaire qui lui a été associé. Néanmoins, le système des interfaces du Go reste trop limité à mon goût : j'en ai déjà parlé sur un ancien journal de gasche.
Prenons l'exemple de la structure d'anneaux en mathématiques : un anneau c'est un type de données que l'on peut ajouter, soustraire et multiplier avec deux éléments neutres pour l'addition et la multiplication. Autrement dit, c'est cette interface de module :
moduletypeAnneau=sig(* le type des éléments de l'anneau *)typet(* les éléments neutres *)valzero:tvalone:t(* les opérations *)valadd:t->t->tvalneg:t->tvalmul:t->t->tend
Plutôt que de dire que l'on peut les soustraire, je préfère exprimer l'axiomatique en disant que l'addition est une opération inversible d'où la fonction neg. À partir de là, dès que l'on a une telle structure, on peut définir dessus le polynôme X^{2} + X + 1 :
Le principe derrière les type classes de Haskell ou les traits de Rust est de dire que pour un type donnée on ne peut définir qu'une interface Anneau sur ce type. Autrement dit, ils considèrent que le type Anneau with type type t = a est un singleton pour tout type a (où plutôt le compilateur garantie que l'on ne définit pas deux valeurs distinctes de ce type), ce qui est trivialement faux mais en pratique largement suffisant. Les interfaces de Go, c'est un peu la même idée mais en beaucoup moins bien : tu ne peux pas définir l'interface Anneau par exemple, il n'est pas possible de définir des opérateurs binaires sur le type t dans les interfaces de Go.
En OCaml, comme le type en question est rarement un singleton, il faut explicitement passer le dictionnaire en argument à la fonction f, même s'il y a déjà eu des propositions pour le rendre implicites dans certaines situations.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Performance
Posté par kantien . En réponse au journal Moi, expert C++, j'abandonne le C++. Évalué à 4. Dernière modification le 05 juin 2019 à 17:59.
Ça l'est : tu veux faire du polymorphisme ad-hoc; mais je ne vois pas où on a besoin de typage dynamique pour cela.
L'idée du polymorphisme ad-hoc est d'avoir des fonctions qui ont le même nom (ici
Greeting) mais qui opère sur différents types et selon des logiques différentes (à la différence du polymorphisme paramétrique). Ensuite à l'usage (comme dans ta fonctionfoo) la fonction effectivement utilisée est choisie en fonction du type du paramètre (type base dispatch). C'est exactement ce que font les type classes de Haskell et les traits du Rust. Cette manière de faire est bien plus intelligente (j'ai envie de dire moins inepte) que l'approche de l'orienté objet. En OCaml on passe par des modules et foncteurs pour faire cela (avec une perte de l'implicite) et il me semble (mais là je suis moins sûr) que les template du C++ peuvent servir à cela.Pour présenter grossièrement l'idée, il s'agit d'associer à un type un dictionnaire de fonctions pour opérer dessus, c'est l'interface contre laquelle on veut programmer de manière générique. En fonction du type du paramètre, le compilateur choisira le dictionnaire qui lui a été associé. Néanmoins, le système des interfaces du Go reste trop limité à mon goût : j'en ai déjà parlé sur un ancien journal de gasche.
Prenons l'exemple de la structure d'anneaux en mathématiques : un anneau c'est un type de données que l'on peut ajouter, soustraire et multiplier avec deux éléments neutres pour l'addition et la multiplication. Autrement dit, c'est cette interface de module :
Plutôt que de dire que l'on peut les soustraire, je préfère exprimer l'axiomatique en disant que l'addition est une opération inversible d'où la fonction
neg. À partir de là, dès que l'on a une telle structure, on peut définir dessus le polynôme X^{2} + X + 1 :Le principe derrière les type classes de Haskell ou les traits de Rust est de dire que pour un type donnée on ne peut définir qu'une interface
Anneausur ce type. Autrement dit, ils considèrent que le typeAnneau with type type t = aest un singleton pour tout typea(où plutôt le compilateur garantie que l'on ne définit pas deux valeurs distinctes de ce type), ce qui est trivialement faux mais en pratique largement suffisant. Les interfaces de Go, c'est un peu la même idée mais en beaucoup moins bien : tu ne peux pas définir l'interface Anneau par exemple, il n'est pas possible de définir des opérateurs binaires sur le typetdans les interfaces de Go.En OCaml, comme le type en question est rarement un singleton, il faut explicitement passer le dictionnaire en argument à la fonction
f, même s'il y a déjà eu des propositions pour le rendre implicites dans certaines situations.Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.