DEV Community

💻 Documentation as code

Adam Coster on April 08, 2021

Programmers hate writing documentation. Most programmers, anyway. That's just stuff that gets in the way of the Real Work™, right? The truth is th...
Collapse
 
hassan_schroeder profile image
Hassan Schroeder

Expressive tests make excellent documentation that by definition can't get out of sync with the actual code, regardless of language.

And Elixir, for instance, lets you document each function with code examples that get run along with your unit tests, so that explicit documentation stays in sync with the function code. (See elixir-lang.org/getting-started/mi...)

Collapse
 
adamcoster profile image
Adam Coster

Ooooh, that's neat! The trick there would be finding such a system that has full support in the IDE (intellisense, linting, etc). I'll have to poke around for JavaScript/Typescript equivalents.

Collapse
 
stereoplegic profile image
Mike Bybee • Edited

Uh, JSDoc? One setting in VS Code for Intellisense (enable for JavaScript), one ESLint plugin (eslint-plugin-jsdoc), and you no longer need TS for static type checking. You can (and probably should) document examples too.

Actually install jsdoc as a dev dependency (which isn't required for the above paragraph, instead just requiring JSDoc comment syntax), and you get a generator for code docs.

Thread Thread
 
adamcoster profile image
Adam Coster

JSDoc is great, and gets at a subset of the general problem.

JSDoc doesn't cover all the functionality that Typescript does for type information, and is quite verbose in comparison. Using both allows Typescript to handle types and JSDoc to handle non-code metadata (explanations, samples), which can all be pulled together with TypeDoc and similar tools.

Thread Thread
 
stereoplegic profile image
Mike Bybee

True. You have to write fewer types just for the sake of other types.

Thread Thread
 
berkmann18 profile image
Maximilian Berkmann

JSDoc is nice until you want to generate the documentation where you then feel like you're using an unmaintained tool; documentation.js is a good alternative although TS removes the need for verbosity and the other pros it gives.

Collapse
 
nickmaris profile image
nickmaris

In the following I would add "The code must be written within your time and budget constraints" as this applies to documentation too. Anyway, its the kind of things that you have to fail to appreciate it and only if you are willing to work with people who care about quality in any aspect. Sometimes we let ourselves get trapped in environments that don't care about quality in any form.

The code must solve the problem at hand.
The code must be easy to maintain.
The code must be efficient enough.

Collapse
 
andrebell profile image
Andre Alexander Bell

I personally think, that documentation is not the last step. If you really document your reasoning to why you solve a task at hand the way you did, then documenting is the key thing to do first.

If you think this to the edge you indeed end with “literate programming”, where you compile documentation into code and then compile that code into the product. This was mentioned in the comments before, but at least I drop a link:

en.m.wikipedia.org/wiki/Literate_p...

Collapse
 
adamcoster profile image
Adam Coster

Agreed! I saw somebody refer to this general idea as "Executable Documentation", and another as "Documentation-Driven Development." In that case I've been practicing "Document-Driven Tools-Driven Test-Driven Development" (docs first, then appropriate external tooling, then tests, then code).

Collapse
 
bertilmuth profile image
Bertil Muth

This is a topic I have been thinking about and working on for a long time. I‘m a big fan of “living documentation” - documentation that is never outdated because it is generated from the code or other technical artifacts (like the API docs you mentioned).

I’ve created a library for representing use cases as code, including complicated workflows, with the option of generating documentation from it: github.com/bertilmuth/requirements...

I’ve also created a library for generating diagrams from source code: github.com/diagramsascode/diagrams...

You can also run it as a script using JBang. Here’s the gist:
gist.github.com/diagramsascode/90b...

Collapse
 
paddy3118 profile image
Paddy3118

Having code in addition to comments that describe that code is a "Don't Repeat Yourself" (DRY) principle violation.

Comments can be repetitive but don't have to be even if they describe code. They could, for example, name an algorithm being used.

Comments on what is being done rather than the how, can also be of use. especially when code is changed for performance reasons.

Collapse
 
adamcoster profile image
Adam Coster

Yep, definitely! The best comments are those that are least likely to become incorrect when the code changes.

Collapse
 
cubiclesocial profile image
cubiclesocial

Programmers hate writing documentation. Most programmers, anyway.

I don't. For me, it's probably the most enjoyable and exciting part of writing software because it usually represents the last step of a software release, which means something's about to head out the door. Also, while writing documentation, I usually am looking at the source code and typically spot at least one or two last-minute mistakes (bugs) that would have made it into the release.

Basically, if you aren't writing documentation for your software, you are missing out on supplying your customers with good documentation such that they will constantly bother you by opening tickets/issues (i.e. waste your time) AND your software will have more bugs in it. That's right, good documentation = fewer open issues on issue trackers. For me, most issues that get opened are actually documentation bugs, not software bugs (e.g. not enough code samples such that users try to use my software incorrectly and get lost/confused).

Collapse
 
adamcoster profile image
Adam Coster

I absolutely agree. Documentation is a lot like testing: at first it feels like it's in the way of "productivity", but once you've had a project in use for more than a few weeks you quickly learn how much time you lose later by not front-loading tests and docs.

I also used to write the docs last, but eventually I started writing the docs first, then the tests, and finally the code. That's helped a lot to prevent me from creating features I didn't actually need, and from having to redesign APIs after realizing I hadn't covered all use cases.

Collapse
 
tinkertim profile image
Tim Post

So, disclaimer - I work for Swimm, and we're doing a lot of innovating around the coupling of documentation to the code it supports. None of these concepts are new, but tooling around them that ultimately resembles a deliberate system instead of something haphazardly cobbled together is sorely lacking. There's also quite a bit of variance in disciplines based on what you're building.

In many modern systems, documentation can actually be the symphony that weaves a lot of robots together. For instance, if you're using Kubernetes, you can generate ingress controller and service mesh mappings directly from OAPI/Swagger docs that literally "just work". So I think we're going to meet some very interesting use cases coming from the gitops / infrastructure as code family in the coming years which will likely transcend into the way that we handle docs that depend on more human interactions.

What I like about what we're building at Swimm is that we couple docs to snippets within the documentation itself and can verify that all documentation is relevant / up-to-date with the current state of the code at the CI/CD level, while we try our best to fix anything that can be automatically reconciled to reduce the maintenance load. Orgs can either block PRs if there are documentation issues, or just open pull requests and everyone agrees they get settled at some determined point in the future that is a bit more specific than "later."

What this encourages is exactly what you're talking about toward the end of the middle of your post - that narrative that explains the rationale, the "why", the dragons that await foolish travelers who don't heed the warnings, and even the directions something might take.

I feel like we're going to be talking about this a lot more in the years to come as more and more organizations migrate to microservices, where you can essentially "onboard" 200+ times during a two year tenure depending on how many services there are, and there's soooo much more you actually need to know than what works conveniently in comments.

Collapse
 
jhelberg profile image
Joost Helberg

Great write! Have a look at literate programming. Also, every business decision leading to code should be documented in such a way that the dependency is clear and ready to be found when the business decision changes.

Collapse
 
ceddlyburge profile image
ceddlyburge

This post talks about automatically generating markdown / uml diagrams from your existing tests. freecodecamp.org/news/how-to-creat...

Collapse
 
lepinekong profile image
lepinekong

Not release yet but grafcet.online is a meta drawing tool meant first to learn or teach programming but also to do visual code design : there's no separation between code and documentation, the mantra being "learning is modeling and modeling is learning". It is agnostic as it copes with any programming language (mainstream and not mainstream past or future), encompasses state machine as it is based on Grafcet which is a synthesis of petrinet and state machine used traditional in automation industry but I expand it now, but it is in a familiar form so that it more ressembles scratch than uml state machine :) Above it is scalable and fractal anything visual tend not to be scalable, I do aim for scalability. In fact I'm now eating my own dog food, with 25000 lines of js code for now.

Collapse
 
phongduong profile image
Phong Duong

Great post. Thank you for sharing

Collapse
 
nvcnvn profile image
Nguyễn Văn Cao Nguyên

Gherkin provide a great "framework" for writing Documents as Code ;)
cucumber.io/docs/gherkin/

English is not my native language, so the world "testing" confused me when writing automated test, I away think tests are "documents that can check their own correctness".

Collapse
 
itsmnthn profile image
Manthankumar Satani

Outstanding craftwork learned few things, do share as you explore.

Collapse
 
habutre profile image
Rogério Ramos • Edited

I have a strong preference for RestDoc+Asciidoc rather Swagger, it’s integrated with tests while documents the API

And as mentioned before, good unit tests works very well as a live/integrated documentation

edit: it’s for Java/Spring

Collapse
 
habutre profile image
Rogério Ramos

Someone knows some doc/test tool that can track live code for events in even-driven architecture?

Collapse
 
zilti_500 profile image
Daniel Ziltener

A great idea would be literate programming, stuff like NoWeb, but there's pretty much no tooling for it so people shy away from using it.

Collapse
 
manvillej profile image
Jeff Manville

why write two documents when one will do? between the code, tests, comments, and naming conventions; documentation serves no purpose other than checking a box.

Collapse
 
adamcoster profile image
Adam Coster

All of those things are forms of documentation. The question is who needs to know what about the project, and then ensuring that all stake holders have access to sufficient documentation that is likely to be accurate. There's definitely no reason to add a form of documentation that isn't needed by anyone!