Polymorphisme ad hoc - Ad hoc polymorphism

Dans les langages de programmation , le polymorphisme ad hoc est une sorte de polymorphisme dans lequel des fonctions polymorphes peuvent être appliquées à des arguments de types différents, car une fonction polymorphe peut désigner un certain nombre d'implémentations distinctes et potentiellement hétérogènes selon le type d'argument(s) auquel(s) il est appliqué. Lorsqu'il est appliqué à des concepts orientés objet ou procéduraux, il est également appelé surcharge de fonction ou surcharge d'opérateur . Le terme ad hoc dans ce contexte n'a pas vocation à être péjoratif ; il se réfère simplement au fait que ce type de polymorphisme n'est pas une caractéristique fondamentale du système de types . Ceci contraste avec le polymorphisme paramétrique , dans lequel les fonctions polymorphes sont écrites sans mention d'un type spécifique, et peuvent donc appliquer une seule implémentation abstraite à n'importe quel nombre de types de manière transparente. Cette classification a été introduite par Christopher Strachey en 1967.

Reliure anticipée

Le polymorphisme ad hoc est un mécanisme de répartition : le contrôle se déplaçant à travers une fonction nommée est envoyé à diverses autres fonctions sans avoir à spécifier la fonction exacte à appeler. La surcharge permet à plusieurs fonctions prenant différents types d'être définies avec le même nom ; le compilateur ou l' interpréteur s'assure automatiquement que la bonne fonction est appelée. De cette façon, les fonctions ajoutant des listes d' entiers , des listes de chaînes , des listes de nombres réels , etc. pourraient être écrites et toutes appelées append - et la bonne fonction d' ajout serait appelée en fonction du type de listes ajoutées. Cela diffère du polymorphisme paramétrique, dans lequel la fonction devrait être écrite de manière générique , pour fonctionner avec n'importe quel type de liste. En utilisant la surcharge, il est possible qu'une fonction effectue deux choses complètement différentes en fonction du type d'entrée qui lui est transmise ; ce n'est pas possible avec le polymorphisme paramétrique. Une autre façon de considérer la surcharge est qu'une routine est identifiée de manière unique non par son nom, mais par la combinaison de son nom et du nombre, de l'ordre et des types de ses paramètres.

Ce type de polymorphisme est courant dans les langages de programmation orientés objet , dont beaucoup permettent aux opérateurs d'être surchargés d'une manière similaire aux fonctions (voir surcharge d'opérateurs ). Certains langages qui ne sont pas typés dynamiquement et qui manquent de polymorphisme ad hoc (y compris les classes de types) ont des noms de fonction plus longs tels que print_int, print_string, etc. Cela peut être considéré comme un avantage (plus descriptif) ou un inconvénient (trop verbeux) selon le point de vue de chacun .

Un avantage qui est parfois obtenu de la surcharge est l'apparence de spécialisation, par exemple, une fonction avec le même nom peut être implémentée de plusieurs manières différentes, chacune optimisée pour les types de données particuliers sur lesquels elle opère. Cela peut fournir une interface pratique pour le code qui doit être spécialisé dans plusieurs situations pour des raisons de performances. L'inconvénient est que le système de types ne peut pas garantir la cohérence des différentes implémentations.

Étant donné que la surcharge est effectuée au moment de la compilation, elle ne remplace pas la liaison tardive telle que trouvée dans le sous-typage polymorphism .

Reliure tardive

Nonobstant la section précédente, il existe d'autres façons dont le polymorphisme ad hoc peut fonctionner. Considérons par exemple le langage Smalltalk. Dans Smalltalk , la surcharge se fait au moment de l'exécution, car les méthodes (« implémentation de la fonction ») pour chaque message surchargé (« fonction surchargée ») sont résolues lorsqu'elles sont sur le point d'être exécutées. Cela se produit au moment de l'exécution, après la compilation du programme. Par conséquent, le polymorphisme est donné en sous-typant le polymorphisme comme dans d'autres langages, et il est également étendu en fonctionnalité par le polymorphisme ad hoc au moment de l'exécution.

Un examen plus approfondi révélera également que Smalltalk fournit une variété légèrement différente de polymorphisme ad hoc . Étant donné que Smalltalk a un modèle d'exécution à liaison tardive et qu'il fournit aux objets la possibilité de gérer des messages qui ne sont pas compris, il est possible d'implémenter des fonctionnalités en utilisant le polymorphisme sans surcharger explicitement un message particulier. Ce n'est peut-être pas une pratique généralement recommandée pour la programmation quotidienne, mais cela peut être très utile lors de la mise en œuvre de proxys.

De plus, bien qu'en termes généraux la méthode de classe commune et la surcharge de constructeur ne soient pas considérées comme du polymorphisme, il existe des langages plus uniformes dans lesquels les classes sont des objets réguliers. En Smalltalk, par exemple, les classes sont des objets normaux. À son tour, cela signifie que les messages envoyés aux classes peuvent être surchargés, et il est également possible de créer des objets qui se comportent comme des classes sans que leurs classes n'héritent de la hiérarchie des classes. Ce sont des techniques efficaces qui peuvent être utilisées pour tirer parti des puissantes capacités de réflexion de Smalltalk . Des dispositions similaires sont également possibles dans des langues telles que Self et Newspeak .

Exemple

Imaginez un opérateur +qui peut être utilisé des manières suivantes :

  1. 1 + 2 = 3
  2. 3.14 + 0.0015 = 3.1415
  3. 1 + 3.7 = 4.7
  4. [1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
  5. [true, false] + [false, true] = [true, false, false, true]
  6. "bab" + "oon" = "baboon"

Surcharge

Pour gérer ces six appels de fonction, quatre morceaux de code différents sont nécessaires, ou trois , si les chaînes sont considérées comme des listes de caractères :

Ainsi, le nom +fait en réalité référence à trois ou quatre fonctions complètement différentes. Ceci est un exemple de surcharge . (Notez l'ambiguïté dans les types de chaîne utilisés dans le dernier cas. Considérez "123" + "456" dans lesquels le programmeur pourrait naturellement supposer l'addition plutôt que la concaténation. Ils peuvent s'attendre à "579" au lieu de "123456". La surcharge peut donc fournir sens différent, ou sémantique, pour une opération, ainsi que différentes implémentations.)

Les références