My approach is laziness, in the computer science sense of the word. Suppose I’m writing a note called “optics in Haskell”. That note can grow to any conceivable size, enormous, no problem. But as soon as I want something I’ve written in that note to have a second parent, it gets reified into its own note.
For instance, suppose I have a note called “implementationso f prisms”. While I’m writing the “optics in Haskell” note, I start writing about the way Haskell’s Lens library implements prisms. I realize that I’d like to be able to link to that information from the “implementations of prisms” note.
That impels me to create a separate “how the Haskell Lens library implements prisms” note, which both of the previous notes link to.
This is lazy in one sense, but not in another. Every time I write anything, I have to consider (this is immediate evaluation, as opposed to laziness) all the contexts that I would like to be able to find it from. If there’s only one context, it’s the note I’m currently writing in, and I don’t have to do anything beyond write it. But if there are multiple contexts, I have more work to do:
If any of the contexts the data belongs in does not exist, I have to create it. For each of those contexts that does exist, I have to find it. Then I have to break the thing I was writing out into its own dedicated note. Last, for all of those contexts (new or old), I’ve got to create the link.
It’s safe, in the sense that if I do it right I can always find something later. But it’s not fast: the linking described in the previous paragraph is laborious.