Eu suspeito que isso depende da linguagem. Quanto à programação funcional, eu me envolvi principalmente com Haskell, então vou explicar como funciona lá.
O código Haskell é organizado em "módulos", que são basicamente apenas coleções de funções e tipos de dados. Cada módulo é um único arquivo. Um módulo é uma espécie de mistura entre uma classe Java e um pacote Java - o escopo exato do que um módulo faz varia. Um módulo também tem controle sobre quais funções e tipos de construtores serão exportados e quais serão ocultados; isso é semelhante a private
e public
em Java.
Nos meus próprios programas, gosto de fazer com que os módulos façam uma coisa, semanticamente; isso os torna como uma classe Java, exceto que eles podem definir vários tipos de dados. Os módulos que eu uso da biblioteca padrão, como Data.List
, são mais como pacotes - eles fornecem um conjunto de funções utilitárias semelhantes. Isso também é muito semelhante a classes Java estáticas como java.util.Arrays
.
Os módulos também são como pacotes Java, pois podem ser aninhados para maior clareza (acho que isso não afeta o código). Em geral, para um único projeto, dou um nome (digamos Project
) e todos os meus módulos fazem parte disso (por exemplo, Project.Parse
e Project.Run
). Se eu estivesse escrevendo um código mais parecido com uma biblioteca do que com um aplicativo, eu o organizaria com base no que estava fazendo, como Data.List
ou Control.Monad
. Uma grande diferença em relação a outros idiomas é que Haskell incentiva a limitação de E / S e a colocação de tudo em um só lugar. Um grande número de módulos não possui E / S e, para qualquer projeto, eu gosto de ter o máximo de módulos possível.
Como exemplo, estou trabalhando em uma linguagem de programação simples que estou chamando de TPL (sem uma boa razão). Para isso, criei dois módulos simples: o TPL.Parse
que define a representação interna da linguagem e como analisá-la, e o TPL.Run
que executa o intérprete e lida com variáveis e IO. Para compilar e executar o código, geralmente existe um Main
módulo que acaba sendo o ponto de entrada do programa.
Existe uma liberdade significativa na organização das funções em um arquivo; é exatamente isso que eu gosto de fazer. Eu defino meus tipos de dados no topo, antes de serem usados em outros lugares. Logo após definir os tipos de dados, implemento o que for necessário para torná-los parte de suas classes de tipos apropriadas - é como implementar uma interface. Então eu sigo com lógica e várias funções auxiliares, conforme apropriado. Finalmente, eu gosto de ter todas as minhas funções de IO na parte inferior, terminando com main
. Isso deixa claro exatamente o que está fazendo qualquer IO e onde o programa é iniciado.
Portanto, em resumo: as funções estão contidas em módulos, cada um dos quais composto por um único arquivo. Vários módulos podem compor um programa ou biblioteca; o primeiro geralmente inclui um Main
módulo que é seu ponto de entrada. Dentro de um arquivo, existem opções diferentes para organização, mas eu prefiro agrupar tipos de dados na parte superior, E / S na parte inferior e lógica no meio.
What's stopping you from...
Anos e anos de programação com uma mentalidade completamente diferente, a ponto de o código Haskell não computar mentalmente. E, claro, você está assumindo que os projetos reais são sempre corretamente e bem organizado (talvez eles são, mas como é um noob como eu para saber?)