Question

J'écris un interprète pour un langage expérimental.Trois des principales constructions du langage sont les définitions, les déclarations et les expressions.Les définitions peuvent contenir des instructions et des expressions, les instructions peuvent contenir des définitions et des expressions, et un type d'expression peut contenir des instructions.Je représente tous ces éléments en utilisant des types d'union afin de pouvoir facilement utiliser la correspondance de modèles.Idéalement, j'aimerais mettre le code correspondant dans différents fichiers, mais OMake se plaint de problèmes de dépendance circulaire.Pour autant que je sache, les définitions de types circulaires entre modules ne sont pas autorisées.

La seule façon que je connaisse de résoudre ce problème est de définir les trois types à la fois :

type defn = ...
and stmt = ...
and expr = ...

Il semble que cela nécessite que tout le code des types soit dans le même fichier.Y a-t-il un moyen de contourner ce problème ?Comment gérez-vous les définitions circulaires dans votre code ?

Était-ce utile?

La solution

Les définitions récursives doivent apparaître dans le même fichier.Si vous souhaitez séparer les définitions, les instructions et les expressions dans des modules distincts, vous pouvez le faire en utilisant modules récursifs, mais ils devront toujours apparaître dans le même fichier.Les dépendances inter-fichiers DAG-ifying sont l’un des désagréments d’OCaml.

Autres conseils

Ceci est facilement résolu en paramétrant vos types sur les types auxquels ils font référence :

type ('stmt, 'expr) defn = ...
type ('defn, 'expr) stmt = ...
type ('defn, 'stmt) expr = ...

Cette technique est appelée « dénouer le nœud récursif » (en référence au nœud gordien) et a été décrite dans un Journal OCaml article.

Bravo, Jon Harrop.

Une autre solution souvent utilisée consiste à abstraire les types dans les interfaces.Puisque les types sont abstraits dans les interfaces, ces interfaces ne sont pas dépendantes de manière récursive.Dans les implémentations, vous pouvez spécifier les types, et comme les implémentations dépendent uniquement des interfaces, elles ne sont pas non plus récursives.

Le seul problème est que, avec cette solution, vous ne pouvez plus faire de correspondance de modèles sur ces types en dehors de leur implémentation.

Personnellement, mais c'est probablement une question de goût, j'aime avoir tous les types de mon programme définis dans un seul module (je pense que cela aide à la lisibilité du programme).Donc, cette restriction d’OCaml ne me pose pas vraiment de problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top