Skip to content

Nim module that allows you to document return values in-place

Notifications You must be signed in to change notification settings

PMunch/explanations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

explanations

This module is intended as a way to document return values, error messages, or other outcomes of calling a procedure, function, or macro in an in-line fashion. When writing good software it's crucial to properly document how it works, but how we do it is often error prone and can cause more harm than good. This module tries to fix one of the issues with providing good documentation. Namely the disassociation with return values and error messages from the documentation of them. Say you've created a nice little function that can return three different return values. To document this you've got a nice table in your documentation, a little something like this:

func ourSuperFunc(value: int): int =
  ## This procedure can return the following:
  ## ===  ===============================================
  ## 0    The value passed in was low (<100)
  ## 1    The value passed in was medium (>100, < 10_000)
  ## 2    The value passed in was high (>10_000)
  ## ===  ===============================================
  case value:
  of low(int)..100:
    return 0
  of 101..10_000:
    return 1
  else:
    return 2

This looks good, but there is a problem. What happens if we change one of the ranges, but forget to update the documentation? Now the documentation is lying to us about what the function does which is not good. This can happen a lot, especially when multiple people are editing the same code, and someone who wasn't aware of the table made a change. To alleviate this issue this module implements an explained pragma, and an expl semi-template.

Macros

macro explained*(message: string, procDef: untyped): untyped

The explained pragma can be attached to a procedure, a function, or a macro. It will look through the body of what it's attached to and replace any expl instances with the first argument while creating a table of the value repr'ed and the explanation given. This means that we can rewrite the example above with:

func ourSuperFunc(value: int): int
  {.explained: "This procedure can return the following:".} =
  case value:
  of low(int)..100:
    return expl(0, "The value passed in was low (<100)")
  of 101..10_000:
    return expl(1, "The value passed in was medium (>100, < 10_000)")
  else:
    return expl(2, "The value passed in was high (>10_000)")

While this doesn't completely remove the possibility of erroneous documentation, it at least brings the explanation closer to the actual value. Making it easier to spot and to change when the code is changed. You can also export the table to a file by passing -d:exportExplanations=<filename.rst>, which is useful if you are documenting return codes of a terminal application, or strings echoed during execution. If you only want this output you must also pass -d:noDocExplanations which will remove the explanations table from the docstring.

macro addExplanation*(explained: static[tuple[message, explained: string]], procDef: untyped): untyped

Adds an explanation table and message from another procedure, the first element in the explained tuple can be set to an extra message to put before the added table and message.

macro addExplanations*(explained: static[seq[tuple[message, explained: string]]], procDef: untyped): untyped

Same as addExplanation but accepts a sequence of tables to add

macro mergeExplanations*(explained: static[seq[string]], procDef: untyped): untyped

Takes a list of explained procedures and merges them with this procedures table, creating one long table with one shared message (the one that was used for this procedures explanation).

Templates

template expl*(value: untyped, explanation: string): untyped {.used.}

This template only exists to create an error when expl is used outside the explained pragma. See the documentation for explained to see how it is meant to be used.

About

Nim module that allows you to document return values in-place

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages