Introduction
Some R programmers have long sought elegant ways to properly organize their codes into composable and reusable R codes, and maintainable modules with granular import system. Unfortunately, R lacks ergonomics for a long time, until {box} R package came in as your saving grace, as it offers a fresh approach to module system in your respective projects.
The Challenge of Code Organization in R
The lack of proper module system in R is one of the reason why it is so hard to put R into production, not that impossible, just complex and so tough. Let’s look at the common challenges:
- R has
source()function but has few to several important caveats to know. - You have to compose a reusable R code by writing an R package. It is still part of the boilerplates, since you just have to organize R codes then make those R codes to be reused. R packages usually requires plenty of boilerplates, no deep nesting of modules, and most of all, that’s pretty much it. There’s no way to reuse code in any R script files / folders, or employ modules with hierarchical and deep nested structure.
- R has no way to explicitly declare imports and dictate dependencies within and between scripts/directories, aside from writing R packages.
- Maintaining consistency across large codebases can be slow and tedious. Since there’s no granular import system, there’s no way to attach the names from scripts/folders, and you have to use
source()function. - Sharing code between projects categorically.
Enter the {box} Package
All of them solved by {box}, except on distribution and proper declaration of package dependencies which is solved by {carrier}. Before {box}, there are packages out there that actually does a pretty solid job, and those are {conflicted} and {import}, except the former mainly manages the namespace conflicts by declaring and the latter does what {box} can do but less. {box} package is just subjectively but ergonomically more superior than those as it does more: it offers a fresh approach to modular programming within R, bringing better clarity and structure to your projects. It addresses these challenges by introducing a modern, explicit module system that feels natural to both any R veteran and developer coming from other programming languages.
Understanding Modular Programming
Modular programming is a model, a paradigm, that emphasizes the following:
- The ability to break down complexity. When the written program gets larger and larger, there’s a time that you gonna have to divide large programs into smaller, manageable pieces.
- An encapsulation, which keeps related code together and protecting it from external interference.
- Creating clear ways for different parts of your code to interact.
- Making code easy to reuse across different projects.
- Inheriting maintainability, making code easier to understand and modify.
Later, this part explains why a module, in a form of a script or a directory, has a namespace and why they are independent to each other until called.
Coding Style
In this guide, we’ll explore {box} using the package author’s preferred coding conventions. While they differ from standard R conventions, most especially the ‘tidyverse style guide’, understanding them might help you grasp the package’s design philosophy. Visit the article for more information about the coding style.
Don’t worry, if you have another way to write your R code, it’s fine (you could use either other’s coding convention or both of this). You’re free to adapt {box}’s preferred coding style in your own projects. The principles and patterns we’ll learn are independent of specific coding conventions.