I've heard lots of opinions from fellow programmers, saying it's annoying to have to update your signatures in _two_ places.
However, I believe a lot of the extra repetition comes from _the bad design of C++'s classes_, rather than the idea of header files itself.
I've mentioned this briefly before in [C++ without Classes][page:programming/cxx-without-classes], but a lot of redundant editing is born out of C++'s poor implementation of class encapsulation.
In C++, your implementation details come out leaking into the header file.
The `draw_entities` implementation detail---a _private function_---is still very much there!
In OCaml, you would do something similar.
Here's `world.mli`:
```ocaml
type t
val entity : t -> Entity.id -> Entity.t
val update : t -> Game_loop.update_context -> unit
val draw : t -> Game_loop.draw_context -> unit
```
And here's `world.ml`:
```ocaml
type data = {
entities: Entity.t array;
}
type t = data ref
let entity w id = (* ... *)
let update w cx = (* ... *)
let draw_entities w cx = (* ... *)
let draw w cx = (* ... *)
```
(Disclaimer: my knowledge of OCaml is pretty surface level. This is probably not valid syntax.)
Our implementation detail `draw_entities` appears again, but only in the module's interface file.
And that's how I view header files: as _public interface declarations_.
They say, "this is the set of public procedures you can run on these types."
When viewed this way, header files become extremely useful for tracking changes in a module's public API, semantic versioning-wise.
But perhaps more importantly, because headers written with the "public interface" philosophy in mind are so laser-focused on exposing the... well, _public interface_, they become your module's _reference documentation._
My favourite example of this is [Dear ImGui](https://github.com/ocornut/imgui/blob/v1.92.1/imgui.h), which takes this idea to the extreme.
Dear ImGui needs no documentation generator like Doxygen.
It's all right there in the header file, and all you have to do is open it in your text editor and grep for whatever you need at the moment.
Here's an excerpt of `imgui.h` (reformatted to fit my blog's column limit better):
```c
// Windows
// - Begin() = push window to the stack and start appending to it.
// End() = pop window from the stack.
// - Passing 'bool* p_open != NULL' shows a window-closing widget in
// the upper-right corner of the window, which clicking will set
// the boolean to false when clicked.
// - You may append multiple times to the same window during
// the same frame by calling Begin()/End() pairs multiple times.
// Some information such as 'flags' or 'p_open' will only be
// considered by the first call to Begin().
// - Begin() return false to indicate the window is collapsed or fully
// clipped, so you may early out and omit submitting anything to
// the window. Always call a matching End() for each Begin() call,
// regardless of its return value!
// [Important: due to legacy reason, Begin/End and BeginChild/EndChild
// are inconsistent with all other functions such as BeginMenu/EndMenu,
// BeginPopup/EndPopup, etc. where the EndXXX call should only be
// called if the corresponding BeginXXX function returned true.
// Begin and BeginChild are the only odd ones out.
// Will be fixed in a future update.]
// - Note that the bottom of window stack always contains a window
Compare this to grepping through an `.rs` file, which usually yields lots of unrelated results.
I pretty much never grep through Rust files to look at APIs, while I do it all the time in C++.
Perhaps it's a sign that the complexity of JavaScript-heavy online HTML documentation viewers with mediocre search functionality is entirely self-inflicted.\
(I'll give them though that rich text is pretty cool, and [Hoogle's](https://hoogle.haskell.org/) global type signature search is _wicked_ cool. Nothing that a sufficiently advanced LSP server shouldn't be capable of doing, though.)