Mais je trouve que leur forme dans ocaml est très complexe et très peu lisible.
J'ai fini par m'y habituer, mais il est vrai que le langage des modules et foncteurs est assez verbeux. Après sur la syntaxe concrète de définition d'un module sans paramètre, je ne vois pas bien la différence entre l'usage d'accolades ou celle de mots-clés :
moduletypeM=sigtypetvalv:tend(* VS *)moduletypeM={typet;v:t;}
Par exemple, en Coq, où la distinction entre type et valeur n'a pas lieu d'être (les types sont des valeurs comme les autres et vivent dans le même monde), on utilisera la syntaxe des enregistrements pour écrire cela (même si Coq a aussi son système de modules).
RecordM:Type:=mkM{t:Type;v:t;}.
Quoi qu'il en soit, je ne trouve pas la syntaxe concrète pour écrire des modules ou leur signature si illisible que cela. Même dans les usages simples des foncteurs (qui sont des fonctions des modules vers les modules), je trouve la notation assez proche du langage des fonctions du langage.
(* une signature pour exprimer la possibilité de convertir un type quelconque vers un string : c'est la donné conjointe d'un type et d'une fonction de conversion.*)moduletypeShowable=sigtypetvalshow:t->stringend(* à partir d'un tel module, il n'est pas difficile de définir des fonctions pour afficher le type à l'écran. On passera par un foncteur. On commence par étendre la signature précédente pour ajouter des fonctions d'affichage, puis celle du foncteur qui transforme un module du premier genre dans le second*)moduletypePrintable=sigincludeShowablevalprint:t->unitvalprintln:t->unitendmoduletypePrint_abs=functor(M:Showable)->PrintablemoduletypePrint=functor(M:Showable)->Printablewithtypet=M.t
Ici, c'est là que le langage commence à devenir verbeux, mais c'est par nécessité. Un module permet de cacher au monde extérieur la représentation concrète de ses types : pour faire en sorte que les données du type de M : Showable soient compatibles avec celles du module résultant de l'application Print(M), il faut le préciser explicitement via l'annotation with type t = M.t. Sans cela, le vérificateur de type se plaindra :
moduleShow_int=structtypet=intletshow=string_of_intendmodulePrint_abs:Print_abs=functor(M:Showable)->structtypet=M.tletshow=M.showletprintx=print_string(showx)letprintlnx=print_endline(showx)endmodulePrint:Print=functor(M:Showable)->structtypet=M.tletshow=M.showletprintx=print_string(showx)letprintlnx=print_endline(showx)end;;modulePrint_int_abs=Print_abs(Show_int)modulePrint_int=Print(Show_int)(* incompatibilité des types *)Print_int_abs.println1;;Error:ThisexpressionhastypeintbutanexpressionwasexpectedoftypePrint_int_abs.t(* types compatibles *)Print_int.println1;;1-:unit=()
Cependant l'aspect verbeux peut, dans les faits, se limiter aux fichiers d'interface .mli et le code effectif du fichier .ml être tout simplement :
Cela parait peut être évident pour toi qui est tombé dedans que tu es petit.
Je ne suis pas tombé dedans quand j'étais petit : c'est un niveau d'abstraction (auquel je suis largement habitué pour d'autres raisons, et encore je ne trouve pas cela très abstrait) dont j'ai ressenti le besoin, et j'ai appris la façon dont OCaml le met à disposition et à m'en servir. Si on n'en ressent pas soi même le besoin pour des raisons de généralisation, le concept de module semble tombé comme un cheveux sur la soupe.
Les modules ressemblent ici vaguement à des objets, avec des définitions de type dedans, mais avec une autre syntaxe.
Les deux syntaxes sont assez proches : ce sont les mots-clés qui changent. Cela me semble utile, voire conseiller au niveau du principe de moindre surprise, le second généralisant (en quelque sorte) le premier il serait surprenant que la syntaxe ne le signifie pas par un moyen quelconque : autrement on risquerait de confondre les deux notions.
Pour conclure ce commentaire déjà bien long, comme toutes ces questions tournent autour de la notion d'abstraction (fonction, type paramétré, objet, module, foncteur...) il est normal que le lamba-calcul soit un outil théorique de premier choix. Dans ce langage, il n'y a que deux notions fondamentales : l'abstraction (le lambda) et l'usage d'abstraction (l'application). :-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: go 2.0
Posté par kantien . En réponse au journal Pourquoi la recherche en langages de programmation ?. Évalué à 3.
J'ai fini par m'y habituer, mais il est vrai que le langage des modules et foncteurs est assez verbeux. Après sur la syntaxe concrète de définition d'un module sans paramètre, je ne vois pas bien la différence entre l'usage d'accolades ou celle de mots-clés :
Par exemple, en Coq, où la distinction entre type et valeur n'a pas lieu d'être (les types sont des valeurs comme les autres et vivent dans le même monde), on utilisera la syntaxe des enregistrements pour écrire cela (même si Coq a aussi son système de modules).
Quoi qu'il en soit, je ne trouve pas la syntaxe concrète pour écrire des modules ou leur signature si illisible que cela. Même dans les usages simples des foncteurs (qui sont des fonctions des modules vers les modules), je trouve la notation assez proche du langage des fonctions du langage.
Ici, c'est là que le langage commence à devenir verbeux, mais c'est par nécessité. Un module permet de cacher au monde extérieur la représentation concrète de ses types : pour faire en sorte que les données du type de
M : Showablesoient compatibles avec celles du module résultant de l'applicationPrint(M), il faut le préciser explicitement via l'annotationwith type t = M.t. Sans cela, le vérificateur de type se plaindra :Cependant l'aspect verbeux peut, dans les faits, se limiter aux fichiers d'interface
.mliet le code effectif du fichier.mlêtre tout simplement :Je ne suis pas tombé dedans quand j'étais petit : c'est un niveau d'abstraction (auquel je suis largement habitué pour d'autres raisons, et encore je ne trouve pas cela très abstrait) dont j'ai ressenti le besoin, et j'ai appris la façon dont OCaml le met à disposition et à m'en servir. Si on n'en ressent pas soi même le besoin pour des raisons de généralisation, le concept de module semble tombé comme un cheveux sur la soupe.
Les deux syntaxes sont assez proches : ce sont les mots-clés qui changent. Cela me semble utile, voire conseiller au niveau du principe de moindre surprise, le second généralisant (en quelque sorte) le premier il serait surprenant que la syntaxe ne le signifie pas par un moyen quelconque : autrement on risquerait de confondre les deux notions.
Pour conclure ce commentaire déjà bien long, comme toutes ces questions tournent autour de la notion d'abstraction (fonction, type paramétré, objet, module, foncteur...) il est normal que le lamba-calcul soit un outil théorique de premier choix. Dans ce langage, il n'y a que deux notions fondamentales : l'abstraction (le lambda) et l'usage d'abstraction (l'application). :-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.