I was thinking about a bit of a design thing I've notice in certain pedagogical and intentionally small codebases have -- often applications and not libraries -- of having a central file of like foo.h, which contains all of the internal implementation details, usually with each logical sub-system in a sub-area. Each of these logical subsections can have it's own implementation file which can contain internal helper files or internal type definitions that are really not necessarily to leak -- everything in the header file is the API for every unit (but if you're doing this you probably don't care that much about modularity).
Wait stop come back.
I think it's generally considered that using textual inclusion and semi-global states for our module system is unideal and that this is a historical quirk of C, it's also sort of nice because the definitions and general summary of a codebase can sometimes be placed in a core place.
In most languages, function declarations can't have standalone prototypes -- this is reasonable language design, but also means you don't have a natural sort of index and listing location.
If you look at something that has similar tiny scope type stuff, bottle.py has this dynamic where you can't eyeball the general layout of everything in one spot, you have to jump around. But otherwise it kind of has similar stuff going on in terms of breaking it up into sections?
I will probably add more here as I can think of them
I think a general example might be e.g.
/** @file interp.h */
/// various utilities & portability stuff
/// util.c
void ;
/// representation of values
/// value.c
typedef struct Value;
typedef struct Func;
typedef struct CallNode;
/// parsing values into nodes
/// parser.h
typedef struct AstNode;
typedef struct CallNode;
typedef struct BranchNode;
typedef struct AssignNode;
void ; /// whatever
/// Environment & scope management
/// env.h
typedef struct Env;
Env* ;
void ;
bool ;
Env* ;
/// garbage collection
/// gc.c
void ;
/// interpretation and AST walking
void Status ;
void Status ;
/// main.c
int ;
These aren't really going for the same thing, the but Single File Libs sort of look at stuff trying to have a certain small scale legibility?
I mean kinda!
Anytime you change any part of the API in the header you're gonna have to recompile every object file. For a lot of projects that's definitely not worth it, but for smaller scale stuff, I think it's fine, and it sorta of makes it easy to get a full...scale?