The following is not intended to make you feel bad or to claim that you are bad. It’s really intended to explain what the experience is like for someone who doesn’t know what they’re doing — which is why I’m reading the docs, right?
I just did my usual experiment and tried to read the documentation for Hashtbl in Core.
First I went to:
Then I clicked through to API docs: https://ocaml.janestreet.com/ocaml-core/latest/doc/core/index.html
which told me “the full API is browsable here”: https://ocaml.janestreet.com/ocaml-core/latest/doc/core/Core/index.html
I don’t see Hash there (note, doing it I made the mistake of looking for Hash instead of Hashtbl for a bit, but see below, this actually leads me to a slightly better result than otherwise), so I try clicking through to Core_kernel as suggested at the top: https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/
Which immediately tells me “Deprecated [since 2018-03] Use Core_kernel directly instead” and who knows what this means, but never mind, I fearlessly scroll forward looking for Hash, and find
module Hash = Core_kernel__.Import.Hash, which I click through on: https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel__/Import/#module-Hash
This brings me to the
Module Core_kernel__.Import where there’s an entry for
module Hash = Base.Hash which I click on: https://ocaml.janestreet.com/ocaml-core/latest/doc/base/Base/#module-Hash
Now I’m on the page for
Module Base, and I realize, looking at it, that I really want
Hashtbl but it is listed as
module Hashtbl : sig ... end and I can click through to: https://ocaml.janestreet.com/ocaml-core/latest/doc/base/Base/Hashtbl/
Note that I’m now seven levels of clicks in.
But this is finally promising, I’m on the page with
Module Base.Hashtbl. Sadly, as I scan down it, it’s a mess. Mostly it’s stuff like
val create : ?growth_allowed:bool ‑> ?size:int ‑> (module Base__.Hashtbl_intf.Key with type t = 'a) ‑> ('a, 'b) t
with no doc string afterwards. What’s a
Base__.Hashtbl_intf.Key? I have no idea. What does
growth_allowed do? What’s the
size, is it the initial size? Who knows. I can guess, being an old timer I know a bit about hash tables. Maybe
growth_allowed means that the table can expand the array and maybe
size is the initial array, but I don’t want to guess, I want to know. Knowing is why you read the docs, they’re not there so you can learn about some options and start conducting experiments.
A large fraction of what I’ve hit after seven pages of clicks is type signatures with word-salad module names involved and no doc strings. I suppose I could read the source but I find the maze of twisty little module includes hard to navigate, and besides, the point of documentation is so I don’t have to read the code.
I could guess some of the time, but for some things, well, what’s a
filter_mapi_inplace do? I’m sure someone smarter than me just looks at the type signature and knows, but I have no clue.
And yes, I understand, the documentation tools aren’t very friendly to Core’s rather intricate module inclusion structure, but as a user that really is cold comfort to me when I can’t find anything quickly if I can find it at all. And once I find stuff, often it’s just type signatures with no documentation strings at all.
Now, I could have taken a right turn at Albuquerque instead of a left turn if I hadn’t mistakenly clicked on
Hash instead of
Hashtbl a couple of times and ended up here two clicks earlier: https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Hashtbl/
…which would seem to be the more correct set of clicks, but having ended up here, at the docs for
Module Core_kernel.Hashtbl, I find literally nothing but type signatures, so maybe the other page was better after all even though it was seven clicks down and not five. What’s the difference between the two? Why does one have some docs and the other has none? Which should I be reading? As a naive user, I have no clue, and I really am a naive user.
So I gave it a reasonable shot and I couldn’t find adequate documentation for the Hashtbl module’s
create function, or much else, and it was a lot of effort to get there.
Where should I have clicked instead? I have no idea. I started on something that claimed to be the way to browse the full API. If there’s some other way to look at it, how would I know what it is without being told?
Note that this experience today is different from previous experiences trying to read the Core documentation only in that the page I started from is a bit different and the long but ultimately unrewarding series of clicks was a bit different. Maybe I’m not doing it right, but no one has made it particularly clear what right would actually be.
And so, even though I suspect Core would be a big help to me — from what I can tell the design is cleaner, more consistent, and much closer to my “only use optional and result, avoid exceptions” way of thinking, I don’t use it.