Je suppose que cela dépend de la langue. En ce qui concerne la programmation fonctionnelle, j'ai surtout touché à Haskell, je vais donc expliquer comment cela fonctionne.
Le code Haskell est organisé en "modules" qui ne sont fondamentalement que des collections de fonctions et de types de données. Chaque module est un fichier unique. Un module est une sorte de mélange entre une classe Java et un package Java - la portée exacte de ce qu’un module fait varie. Un module contrôle également les fonctions et les constructeurs de types à exporter et ceux à masquer. c'est semblable àprivate
et public
en Java.
Dans mes propres programmes, j'aime bien que les modules en fassent un chose, sémantiquement; cela les rend similaires à une classe Java sauf qu'ils peuvent définir plusieurs types de données. Les modules que j'utilise dans la bibliothèque standard, par exemple Data.List
, ressemblent davantage à des paquets: ils fournissent un ensemble de fonctions utilitaires similaires. Ceci est également très similaire aux classes Java statiques comme java.util.Arrays
.
Les modules ressemblent aussi aux packages Java en ce sens qu’ils peuvent être imbriqués pour plus de clarté (je ne pense pas que cela ait un effet sur le code lui-même). En général, pour un seul projet, je lui donne un nom (par exemple Project
) et tous mes modules en font partie (par exemple, Project.Parse
et Project.Run
). Si j’écrivais un code qui ressemblait plus à une bibliothèque qu’à une application, je l’organiserais en fonction de ce qu’elle faisait, comme Data.List
ou Control.Monad
. Une différence majeure par rapport aux autres langues est que Haskell encourage à limiter les entrées-sorties et à tout mettre au même endroit. Un grand nombre de modules ne font pas du tout d'entrées-sorties et, pour un projet donné, j'aime avoir autant de modules purs que possible.
Par exemple, je travaille sur un langage de programmation simple que j'appelle TPL (sans raison valable). Pour cela, j'ai créé deux modules simples: TPL.Parse
qui définissent la représentation interne du langage et comment l’analyser, etTPL.Run
exécutant l'interpréteur et traitant les variables et les entrées / sorties. Pour compiler et exécuter le code, il existe généralement un Main
module qui constitue le point d’entrée du programme.
Il y a une grande liberté dans l'organisation des fonctions dans un fichier; C'est ce que j'aime faire. Je définis mes types de données vers le haut, avant qu'ils ne soient utilisés ailleurs. Juste après la définition des types de données, j'implémente tout ce dont j'ai besoin pour les intégrer à leurs classes de types appropriées - c'est un peu comme implémenter une interface. Ensuite, je suis la logique et diverses fonctions d’aide, selon le cas. Enfin, j'aime avoir toutes mes fonctions IO tout en bas se terminant par main
. Cela permet de savoir exactement ce que fait une entrée / sortie et le début du programme.
Donc, en résumé: les fonctions sont contenues dans des modules, chacun étant composé d'un seul fichier. Plusieurs modules peuvent constituer un programme ou une bibliothèque. le premier comprend généralement un Main
module qui constitue son point d’entrée. Dans un fichier, il existe différentes options d'organisation, mais je préfère grouper les types de données vers le haut, les entrées / sorties vers le bas et la logique au milieu.
What's stopping you from...
Des années et des années de programmation avec un état d'esprit complètement différent, au point que le code Haskell ne calcule pas mentalement. Et bien sûr, vous supposez que les projets réels sont toujours correctement et parfaitement organisés (peut-être qu'ils le sont, mais comment se fait-il que personne ne me connaisse?)