Comment fais-tu avec des variants et l'approche initiale si tu veux rajouter des int et l'opération d'addition add au langage jouet avec les booléens ?
La réponse un peu triviale c'est que je ne fais pas souvent ça1. Dans mes cas d'usages personnels on peut souvent revenir éditer la définition initiale. Le problème d'extensibilité des données et opérations (parfois connu sous le nom de "Expression problem" qui est assez peu clair, "Extensibility problem" est un nom plus ancien et plus clair) est intéressant et important, mais pour moi c'est un peu comme la récursion ouverte, ou d'ailleurs les GADTs: moins on en a besoin, plus on peut faire simple, mieux on se porte. Dans les programmes que j'ai eu l'occasion d'écrire, j'ai eu la chance de pouvoir toujours utiliser des approches plus simples.
1: Si je voulais vraiment faire ça sans fonctionnalité avancée j'envisagerais d'avoir une définition du type de départ en style "récursion ouverte", avec un constructeur "la suite" qui est paramétré, pour pouvoir faire l'extensibilité après-coup. Ça marche mais c'est assez inélégant à l'usage, puisque si on fait deux couches d'extension il faut traverser deux constructeurs "la suite" et il y a des paramètres dans tous les coins. De plus pour faire ça avec les GADTs il faut abstraire sur un type paramétré, donc un foncteur, ça peut vite devenir lourd aussi.
Après le fait d'avoir plusieurs définitions de données différentes mais proches et liées entre elles (sous-ensembles image de traductions, etc.), qui est aussi bien résolu par les variantes polymorphes, se pose plus souvent dans ma "vraie vie", par exemple quand on écrit des compilateurs c'est typique, et encore plus avec les approches "Nanopass" qui sont assez populaires (Scheme, Scala), avec plein de passes qui touchent seulement une construction ou deux. Souvent les gens utilisent de la métaprogrammation pour faire ça (fonctions de traversée auto-générées, etc.), au lieu d'essayer d'avoir cette modularité dans le langage (à quel coût à l'utilisation ?).
[^] # Re: Tagless final un chemin vers MetaOCaml en bibliothèque ?
Posté par gasche . En réponse au journal Découvrir MetaOCaml dans son navigateur. Évalué à 3.
La réponse un peu triviale c'est que je ne fais pas souvent ça1. Dans mes cas d'usages personnels on peut souvent revenir éditer la définition initiale. Le problème d'extensibilité des données et opérations (parfois connu sous le nom de "Expression problem" qui est assez peu clair, "Extensibility problem" est un nom plus ancien et plus clair) est intéressant et important, mais pour moi c'est un peu comme la récursion ouverte, ou d'ailleurs les GADTs: moins on en a besoin, plus on peut faire simple, mieux on se porte. Dans les programmes que j'ai eu l'occasion d'écrire, j'ai eu la chance de pouvoir toujours utiliser des approches plus simples.
1: Si je voulais vraiment faire ça sans fonctionnalité avancée j'envisagerais d'avoir une définition du type de départ en style "récursion ouverte", avec un constructeur "la suite" qui est paramétré, pour pouvoir faire l'extensibilité après-coup. Ça marche mais c'est assez inélégant à l'usage, puisque si on fait deux couches d'extension il faut traverser deux constructeurs "la suite" et il y a des paramètres dans tous les coins. De plus pour faire ça avec les GADTs il faut abstraire sur un type paramétré, donc un foncteur, ça peut vite devenir lourd aussi.
Après le fait d'avoir plusieurs définitions de données différentes mais proches et liées entre elles (sous-ensembles image de traductions, etc.), qui est aussi bien résolu par les variantes polymorphes, se pose plus souvent dans ma "vraie vie", par exemple quand on écrit des compilateurs c'est typique, et encore plus avec les approches "Nanopass" qui sont assez populaires (Scheme, Scala), avec plein de passes qui touchent seulement une construction ou deux. Souvent les gens utilisent de la métaprogrammation pour faire ça (fonctions de traversée auto-générées, etc.), au lieu d'essayer d'avoir cette modularité dans le langage (à quel coût à l'utilisation ?).