Lazi

Comment surcharger les fonctions

Contexte

Comment définir par exemple la fonction + si l'on veut qu'elle ait de nombreuses utilisations "ajout de chaînes de caractères etc" ?
La surcharge dynamique, quand on utilise déjà un certain type, ne pose pas de problème, je l'utilise déjà.

Question

Comment réaliser la surcharge statique en Lazi ?

Étude

Exemple avec "+"

On veut définir la fonction "+" qui peut prendre en argument des nombres mais aussi des listes etc.

Il serait utile que "+" soit un objet mathématique, sinon ça deviendrait très compliqué. Cela n'empêche pas le compilateur de réaliser des optimisations puisqu'il peut faire des calculs à l'avance.

Pour le choix de la fonction à utiliser, il peut y avoir :

  • des conflits incompatibles (par exemple entre un "int" et un "int modulo 256")
  • des choix compatibles (entre int et float), mais avec des coûts différents.

Habituellement le compilateur utilise la déclaration de type pour savoir quelle fonction utiliser pour le "+". Par exemple si x et y sont des "int" alors il va utiliser "plusInt" à la place de "+". Mais Je trouve important de séparer la vérification de propriété sur le programme (ce qui est habituellement le type-checking) du typage (c'est à dire l'information de ce qu'est la donnée).

Il faudrait plutôt que des objets soient utilisés, par exemple le nombre 5 serait l'objet "number,5" sans préciser s'il doit être traité comme un entier sur n bits, float, vrai entier etc.

Comment définir la fonction + ?
Avec la surcharge on peut vouloir définir en plusieurs endroits, suivant les types en argument. On peut imaginer que l'on veuille répartir la définition d'une fonction sur plusieurs fichiers sources. Un système générique serait de pouvoir définir par ajout d'éléments à un élément de départ, chaque ajout pouvant se faire à différents endroits du source. À partir de ce mécanisme on peut créer toute sorte de définitions, comme une fonction surchargée.

  • Pour pouvoir utiliser ce mécanisme pour la surcharge, il faut qu'à chaque fonction traitant un cas particulier on définisse les types des arguments qui sont acceptés.
  • Comment utiliser ce mécanisme pour le parttern mathching ? C'est fondamentalement la même chose que la surcharge : on pose des conditions sur les arguments.

Optimisation

Tous ces mécanismes sont représentables mathématiquement et peuvent donc être manipulés de sorte que l'on obtienne au final du code optimisé.

Une définition incrémentale spéciale ?

Faut-il tout passer en définition incrémentale (et quand il n'y a qu'un élément, le retourner directement) ou utiliser deux formes de définition ?

Il est mieux de séparer car les types sont utilisés pour 3 choses qu'il vaut mieux permettre d'être séparés :

  • la vérification de propriété
  • la création d'objet
  • la sélection dans les surcharges

Syntaxe de la surcharge

À la place de "$Def x = " on pourrait utiliser "$Def x += ".

Spécifier les sélections dans la surcharge

On peut distinguer les arguments qui sont

  • des variables, où l'on peut spécifier une condition (cela peut être de vérifier un type ou autre comme de vérifier une inégalité).
  • des objets sans variable (comme par exemple "5"), où là cela implique une condition d'égalité.
  • le résultat de l'application d'une fonction pouvant avoir comme arguments l'une des 3 sortes d'arguments : on doit alors résourdre l'équation (en Haskell on réduit la résolution aux cas des constructeurs). Pour arriver à cela, il faudrait que pour certaines fonctions on définisse des fonctions inverses qui serviraient à résoudre l'équation.

Réponse

  • en utilisant des objets pour les choses manipulées
  • en ajoutant un mécanisme de définition incrémentale permetant d'étaler la définition dans les sources