I suspect this depends on language. As far as functional programming, I have mostly dabbled in Haskell, so I'm going to explain how it works there.
Haskell code is organized into "modules" which are basically just collections of functions and data types. Each module is a single file. A module is something of a mix between a Java class and a Java package--the exact scope of what a module does varies. A module also has control over which functions and type constructors to export, and which ones to hide; this is similar to private
and public
in Java.
In my own programs, I like to have modules do one thing, semantically; this makes them like a Java class except that they might define multiple data types. The modules I use from the standard library, like Data.List
, are more like packages--they provide a set of similar utility functions. This is also very similar to static Java classes like java.util.Arrays
.
The modules are also like Java packages in that they can be nested for clarity (I do not think this has any effect on the code itself). In general, for a single project, I give it a name (say Project
) and have all of my modules be part of this (e.g. Project.Parse
and Project.Run
). If I was writing code that was more like a library than an application, I would organize it based on what it was doing, like Data.List
or Control.Monad
. One major difference from other languages is that Haskell encourages limiting IO and putting it all in one place. A large number of modules do no IO at all, and for any given project, I like to have as many modules be pure as possible.
As an example, I am working on a simple programming language I'm calling TPL (for no good reason). For this I have created two simple modules: TPL.Parse
which defines the internal representation of the language and how to parse it, and TPL.Run
which runs the interpreter and deals with variables and IO. For actually compiling and running the code, there is generally a Main
module which is what ends up being the entry point of the program.
There is significant freedom in organizing the functions within a file; this is just what I like to do. I define my data types towards the top, before they are used elsewhere. Right after defining the data types, I implement whatever I need to make them part of their appropriate typeclasses--this is sort of like implementing an interface. Then I follow with logic and various helper functions, as appropriate. Finally, I like to have all of my IO functions at the very bottom ending with main
. This makes it clear exactly what is doing any IO and where the program starts.
So, in summary: functions are contained in modules, each of which is made up of a single file. Several modules can make up a program or library; the former generally includes a Main
module that is its entry point. Within a file, there are different options for organization, but I prefer to group data types near the top, IO near the bottom and logic in the middle.
What's stopping you from...
Years and years of programming with a completely different mindset, to the point that Haskell code doesn't mentally compute. And of course you are assuming that real projects are always correctly and neatly organized (maybe they are but how's a noob like me to know?)