{admiral} Manifesto
For admiral and all extension packages, we prioritize providing our users with a simple to adopt toolkit that enables them to produce readable and easily constructible ADaM programs. The following explains our philosophy, which we try to adhere to across the admiral family of packages. There isn’t always a clear single, straightforward rule, but there are guiding principles we adhere to for admiral. This manifesto helps show the considerations of our developers when making decisions.
We have four design principles to achieve the main goal:
Usability
All admiral functions should be easy to use.
- Documentation is an absolute priority. Each function reference page should cover the purpose, descriptions of each argument with permitted values, the expected input and output, with clear real-life examples—so that users don’t need to dig through code to find answers.
- Vignettes that complement the functional documentation to help users see how best the functions can be applied to achieve ADaM requirements.
- Functions should be written and structured in a way that users are able to read, re-use or extend them for study specific purposes if needed (see Readability below).
Simplicity
All admiral functions have a clear purpose.
We try not to ever design single functions that could achieve numerous very different derivations. For example if you as a user pick up a function with >10 different arguments then chances are it is going to be difficult to understand if this function could be applied for your specific need. The intention is that arguments/parameters can influence how the output of a function is calculated, but not change the purpose of the function.
We try to combine similar tasks and algorithms into one function where applicable to reduce the amount of repetitive functions with similar algorithms and to group together similar functionality to increase usability (e.g. one study day calculation rather than a function per variable).
We strive to design functions that are not too general and trying to fulfill multiple, complex purposes.
Functions should not allow expressions as arguments that are used as code snippets in function calls.
We recommend to avoid copy and paste of complex computational algorithms or repetitive code like checks and advise to wrap them into a function. However we would also like to avoid multi-layered functional nesting, so this needs to be considered carefully to keep the nesting of 3-4 functions an exception rather than the rule.
Findability
All admiral functions are easily findable.
- In a growing code base, across a family of packages, we make every effort to make our functions easily findable.
- We use consistent naming conventions across all our functions, and provide vignettes and ADaM templates that help users to get started and build familiarity. Each admiral family package website is searchable.
- We avoid repetitive functions that will do similar tasks (as explained above with study day example).
- Each package extension is kept focused on the specific scope, e.g. features that are relevant across multiple extension packages will be moved to the core admiral package.
Readability
All admiral functions follow the Programming Strategy that all our developers and contributors must follow, so that all our code has a high degree of consistency and readability.
- We encourage use of tidyverse (e.g. dplyr) over similar functionality existing in base R.
- For sections of code that perform the actual derivations (e.g. besides assertions or basic utilities), we try to limit nesting of too many dependencies or functions.
- Modularity is a focus—we don’t try to achieve too many steps in one.
- All code has to be well commented.
- We recognize that a user or a Health Authority reviewer may have the wish to delve into the code base (especially given this open source setting), or users may need to extend/adapt the code for their study specific needs. We therefore want any module to be understandable to all, not only the admiral developers.
