5g: Documentation

Description
5g functions must be structured and documented.

Learning Objectives
At the end of this course, learners will know:

Prerequisites

Discussion

Documentation is useful to several audiences:

End Users: Function documentation helps users understand what our function's purpose is, what the arguments are, how to use our function, and what version they are using.

Maintainers: Function documentation helps us maintain functions we created long ago, as-well-as those who must maintain our function when we cannot.

Reviewers:  Function documentation helps those who must vet our functions, understand what our functions do and how they work.

And just as there are several audiences, there are also several ways to document our functions.

Internal Documentation

Function Naming

The very first thing any user sees is our function's name. It must be unique within a module (a collection/library of functions within AFE). It should be concise and convey our function's purpose. These two goals, being concise and conveying purpose, are often at odds with each other. The trick is to find a happy balance. 

An example of a function name that errors on being too concise is DB(). This is Excel's depreciation function using the declining balance method. If fails, in my opinion, to convey that purpose. On the other hand, naming it: DEPRECIATIONDECLININGBALANCE() would convey its purpose but fail in being concise. It is also unreadable.

One way we can make it more readable is to use a form of Camel Case notation in which we capitalize only the first letter of each word like so: DepreciateDecliningBalance(). That is far more readable but still not concise.

One way to make names concise is to abbreviate words. Combining this with camel case yields something like: DepnDecBal(). That is more concise but the there is no one standard abbreviation for depreciation nor declining. 

Another way is to use context with abbreviations. Here is an example: DepreciateDB(). In this example, depeciation provides a context by which we can interpret DB as declining balance.

In summary, when creating our function's name, we should strive to be concise and convey purpose. Use Camel Case to improve readability. Use standard abbreviations where they exist, and use context to clarify abbreviations.

Argument Naming

The next thing users see is our function's argument names. Like function names, they should be concise and convey their purpose. Follow the guidelines for function naming. 

Unlike function names, arguments names only need to be unique within the function. We are likely to use the same argument names in different functions. Because we will see the same arguments in different functions, try to be consistent. For example, if our function needs an opening balance passed to it, decide if we want to use Opening or OpeningBalance and use whatever we choose in all of our other functions.

NOTE! Users do not type argument names so making them concise isn't as important for arguments.

NOTE! In general, avoid single letter arguments unless the context makes them obvious. An example is MAKEARRAY() where R for row and C for column is easily understood.

Inline Help

The next level of documentation for end users is our function's inline help. Here is where we can:

As well as anything else we want to tell the user.

Documentation Block

We creat this block from two types of comments: Multi-line, and Name Manager comments. It starts with a multi-line comment designator /*.  The end multi-line comment designator is */. Everything in between is a comment. 

The Name Manager comment appears in the Name Manager's comment box. Its start designator is /**. Its end designator is the same as the multi-line comment: */

This block contains some basic information including:

Structure Labels

When we have to maintain our functions, these labels just make it easier to focus our attention where it is needed.

Constant Naming

There is a difference between data and information. Data is values like the number 12. Information is data with context. 12 months per year is data with context. Naming constants turns data into information which helps us understand our formulas. We could name our constant MonthPerYear or we could abbreviated it as MPY, which would be considered a mnemonic, and add a single line comment to clarify the abbreviation like so:

MPY, 12, //Months Per Year

When used in a formula we would see something like:

Allocation, AnnualAmount / MPY,

Step Naming

When those who must maintain the function look inside, it is likely they will encounter LET() functions. When we look at the formulas inside LET(), we see what look like variable names before a formula. These are not variables in the traditional programming sense in that we cannot just assign values to them anywhere within our function. These are internally named formulas. The value they have is the formula's result. The term Internally named means the name inside the LET() function is understood inside the LET() function but does not exist outside the LET() function. 

I refer to these named formulas as let steps. Each let step must be unique within the LET() function. They should be concise and convey purpose. 

NOTE! LET() functions can be nested. Let step names in an outer LET() are accessible by inner LET() functions.

External Documentation

Web

This is optional but Excel provides a webpage for each of its functions and we recommend doing the same for 5g functions.

Summary

Documentation helps end users use our functions, helps reviewers understand our functions, and helps us maintain our functions. While it appears we have a lot of documentation, some of it comes from templates, some of it is common sense naming choices, and the rest requires a few minutes of extra typing.

Navigation