DevelopmentOn documentation

On Documentation

TLDR; It’s usually better to generate documentation from code instead of writing and trying to maintain it.

On source of truth

In software engineering, there always seem to be two sources of truth that seem to usually matter, the spec from a PO or stakeholders (technical or non-technical) which either marks a point in future what they would like the product to be or also past point to document what the product was supposed to be. Many of us might have encountered these writings usually in confluence or some combination of other tools to hold for example product spec, diagrams, system documentation etc

On the other hand there is a alternate source of truth which I personally value as the bible and that is the actual code. No matter how well a documentation is written, fact lies in code. Probably the difference between the spec and code is what we call bug but bug is a brutal truth which hides in code not in spec.

On futility of documentation

In my career never have I encountered any single piece of documentation that stood the test of time. Everything expires and as more things are written bigger burden they become to maintain.

At this point in career I truly and deeply believe code and the documentation are the same. So, does that mean the diagrams that we see maintained, additional context behind why a function was written, the product decisions and historical references are ? Certainly not, but if we are to truly get these benefits its better that it comes from or lives with the actual bible which is code.

Some explorations

In my team, I of course say these same things day in and out but living what I preach is the only way it makes it real. Here are some of the explorations I want to journey through and get my idea across if anyone happen to read this piece.

1. Self Documenting code:

Code these days are turning quickly into commodity with AI and with every systems/library code are getting easier to read and understand. Plus industry moving to DSL like declarative code for infra to UI is pretty self explanatory. Still its an art to write a self documenting code, an honest intent towards it goes long way.

2. State machines:

This is not a new concept in any way but a very useful tool in my opinion. It helps us model a discrete sets of states that can occur with possibly discrete sets of input. I am trying to refer to DFAs, deterministic finite automatas that can give us clear picture of how a system works. I have a micro-library on swift at https://github.com/NutanNiraula/Automaton that I modify based on project I use it for. There is sometimes better and smarter code that can do same thing a state machine could do, but I have come to like them for their documentation capabilities.

For example, navigation in apps usually fall easily into this pattern where I can model discrete sets of pages with discrete events that can cause the navigation to happen and since I can easily model this in state machine, I can easily also convert the modelled code to something like a mermaid diagram through all sorts of tooling. I prefer Sourcery an execellent meta-programming library in swift. I want to keep this blog simple so, I won’t go into complex example but lets look at the mermaid diagram below and ruminate how it can help us. Since, mermaid diagrams are simple strings, its easy to convert a programming model that is deterministic to a mermaid diagram.

Of course, navigation is not the only feature that could be modelled this way, deeplinks, or an application logic in viewModels, business logic in Backend (I see many folks using statemachines on backend), anything that feels to fall here could benefit.

As an exercise for the readers, try to go through the sets of diagrams in mermaid and see what else you can convert from your code with little bit of tooling. With native rendering capabilities of git repos in Github or knowledge management tools like Obsidian, its a godsend format begging to be used more.

3. Parsing and Templating:

JSON is an interesting and now ubiquitous data format almost all programmers are familiar with. This can be used in creative ways to convert to diagrams or documentation. And I daresay not only JSON or any parseable file format could be used, csv, xml, json, pkl pick your poison.

I want to go on a simple exploration of design tokens here. Design token are kind of hot thing right now in the world of design system although, at the point of writing this there is no official spec ready, still feel free to explore the draft spec at https://tr.designtokens.org/format/ With tools like deign token studio for Figma, https://tokens.studio its trivial to produce json representation of the design tokens used in figma and then sync it to a git repo. With this in place, possibilities are already endless, we have a single source of truth in this case figma design to drive other truths, mobile apps design system library, web app design system css, documentation through static site whatever.

I utilized a simple templating language like mustache to get hold of this json and then utilize the template string to produce design system for all the platforms including documentation. The idea is trivial, implementation requires collaboration but its worth it to drive everything from single source of truth and not write stuffs by hand. We don’t need AI to generate code if the things we need already fall in pattern, I daresay this is far better than using AI hype for these stuffs.

4. Documentation engines:

Everyone kind of knows OpenAPISpec, the swagger file that everyone is fond of using. Its a good example of api doc produced from the spec in code, and actually many teams go step forward to also generate their api clients in frontend from this spec. Likewise there are good documentation engines to do this for any kind of api, including ones in binary formats like xcframeworks.

Apple actually has a new compiler architecture called DoCC, documentation compiler and it can produce some really nice documentation from code. I love these ones for example, Swift Godot or Composable architecture I would keep systems like storybooks under same category https://storybook.js.org in a sense that they utilize code to produce tooling around it.

My advice is to look for these tools and you will be surprised how far you can take documentation alongside your code. Existing toolings in IDE also allow for some markups like //TODO: or //FIXME: where some ideas could be stored and searched through. Also, nothing beats tried and truem small comments left inside code to indicate why it was done that way and PR review descriptions and git commit messages are all the places that have existing tooling around us to check for info in case anyone is lost; that person could be future us.

5. Tests:

This is probably the obvious one. Unit tests or any others (Snapshot tests, Integration, UI, Contract tests …) are a great source of documentation of how code works and contantly validate the code in CI or local environment for devs. Any kind of these automatable pieces of spec, gives constant reminder how things work and how things should not break.

That’s it for now, I will definitely add more points as I remember them but lets try to make the workplace less painful by not writing wrong kind of documentation and opting in instead for the ones that are more valuable and can be little more easier to maintain.