Partial Implementation Plan on R
1. Scope
This plan applies a subset of specification‑driven, recursive refinement methodology to R software projects. Full implementation of the methodology is not achievable in R because static type checking is unavailable. The following subset is technically feasible:
- Structural specification using R’s formal class systems (S4, R7) or runtime contract packages (
{interface}, {typed})
- Skeleton–tissue separation via R6 abstract classes + directory conventions + CI checks
- Four‑layer validation gates (syntax, static analysis, unit tests, runtime contracts)
- Recursive refinement with fixed premises using Git tags,
{renv}, roxygen2, and NEWS.md
2. Core Principles (Technical Translation)
| Principle |
R Technical Equivalent |
| Intent–Structure–Implementation Separation |
Formal class definitions (S4/R7) or interface definitions ({interface}) as specification; implementation in separate modules |
| Skeleton–Tissue Architecture |
Skeleton: R6 abstract classes or S4 virtual classes (manual, immutable). Tissue: concrete R6/S4 classes (generated, replaceable) |
| Generative Conformance |
Code generation from specification (LLM or templates) followed by validation gates; no static pre‑generation guarantee |
| Recursive Refinement with Fixed Premises |
Git tags + renv.lock + roxygen2 documentation + goodpractice checks at phase boundaries |
| Inferential Information Density |
Measured via cyclomatic complexity ({cyclocomp}), test coverage ({covr}), and dependency graph metrics ({pkgnet}) |
3. Structural Specification
| Method |
Specification Form |
Validation |
Use Case |
| S4 classes |
setClass() with slots and contains="VIRTUAL" |
Runtime (validObject()) |
Abstract interfaces with inheritance |
| R7 classes |
new_class() with properties and validator |
Runtime |
Modern alternative to S4 |
{interface} |
interface() function defining properties and types |
Runtime (type checking on construction) |
Data models and simple contracts |
{typed} |
%:% type annotation for variables and functions |
Runtime (on assignment/call) |
Function‑level contracts |
3.2 Example: S4 Specification
# Structural specification (skeleton)
setClass("ProcessorSkeleton",
representation = list(state = "character"),
contains = "VIRTUAL",
prototype = list(state = "idle"))
setGeneric("process", function(object, input) standardGeneric("process"))
setGeneric("get_result", function(object) standardGeneric("get_result"))
4. Skeleton–Tissue Separation
4.1 Directory Layout
project/
├── R/
│ ├── skeleton/ # Manual, immutable (S4 virtual classes, R6 abstract classes)
│ └── tissue/ # AI‑generated or replaceable (concrete implementations)
├── tests/ # testthat unit tests
├── inst/ # roxygen2 documentation output
├── DESCRIPTION
├── NAMESPACE
├── renv.lock
├── NEWS.md
└── FIXED_PREMISE.md
4.2 R6 Abstract Skeleton Pattern
# skeleton/processor_base.R (manual, immutable)
library(R6)
ProcessorSkeleton <- R6Class("ProcessorSkeleton",
public = list(
run = function(input) {
self$validate(input)
result <- self$process_core(input)
self$cleanup()
return(result)
},
validate = function(input) stop("Abstract method"),
process_core = function(input) stop("Abstract method"),
cleanup = function() invisible(NULL)
)
)
# tissue/processor_impl.R (generated, replaceable)
ProcessorImpl <- R6Class("ProcessorImpl",
inherit = ProcessorSkeleton,
public = list(
validate = function(input) {
if (!is.numeric(input)) stop("Input must be numeric")
},
process_core = function(input) {
return(sum(input))
}
)
)
4.3 Dependency Direction Enforcement (CI)
# Check that skeleton does not source tissue
if grep -r "source.*tissue/" R/skeleton/ 2>/dev/null; then
echo "ERROR: Skeleton cannot depend on tissue"
exit 1
fi
5. Validation Gates
| Layer |
Tool |
Command |
Pass Condition |
| L1: Syntax |
R CMD check |
R CMD check . |
No errors or warnings |
| L2: Static analysis |
{lintr}, {cyclocomp} |
lintr::lint_package() |
Zero lints; cyclocomp ≤ 15 |
| L3: Unit tests |
{testthat} |
testthat::test_dir("tests/") |
100% passing |
| L4: Runtime contracts |
{interface}, {typed}, S4 validObject() |
Embedded in code |
No contract violations during test execution |
All gates are automated via GitHub Actions or similar CI.
6. Recursive Refinement and Fixed Premises
6.1 Fixed Premise Components
| Component |
Tool |
Storage |
| Phase snapshot |
Git tag |
phase-N-complete |
| Environment |
renv.lock |
Commit to repository |
| Public API documentation |
roxygen2 |
man/ directory |
| Specification (interfaces) |
S4/R6/R7 source files |
R/skeleton/ |
| Change log |
NEWS.md |
Commit |
| Quality gate results |
goodpractice::gp() output |
CI log (optional) |
6.2 Phase Workflow
- Plan – Define changes to structural specification (S4/R6 interfaces).
- Approve – Human reviews specification delta.
- Generate – AI generates tissue code (concrete classes) from specification.
- Validate – Run all four validation gates.
- Document – Run
roxygen2::roxygenize() to update documentation.
- Commit –
git commit -m "Phase N: specification changes"
- Tag –
git tag -a "phase-N-complete" -m "Fixed premise for Phase N"
- Repeat – Checkout tag for next phase start.
6.3 API Evolution with Deprecation
# Phase N+1: mark old function as deprecated
old_function <- function(x) {
.Deprecated("new_function")
# old implementation
}
- R ≥ 4.0
- R6 – reference classes with encapsulation
- ooplah – abstract classes for R6
- S4 (base) – formal classes and virtual classes
- interface – runtime interface contracts
- typed – variable/function type annotations
- testthat – unit testing
- lintr, cyclocomp, goodpractice – static analysis
- renv – reproducible environments
- roxygen2 – documentation generation
- pkgnet – dependency graph analysis
- Git – version control and tagging
- GitHub Actions – CI automation
8. Limitations
| Limitation |
Impact |
Workaround |
| No static type checking |
Specification conformance verified only at runtime |
Comprehensive test suites + runtime contracts |
Weak encapsulation (:::) |
Skeleton may accidentally access tissue internals |
CRAN submission disallows :::; CI grep checks |
| Multiple OOP systems (S3/S4/R6/R7) |
Inconsistent specification patterns |
Adopt single system per project (prefer R6 + S4 for interfaces) |
| LLM generation non‑deterministic |
Regeneration may produce different code |
Fixed seeds, regeneration retries, validation gates |
| S4 inheritance initialization issues |
Complex hierarchies cause errors |
Keep inheritance depth ≤ 3; prefer composition |
9. Conclusion
A partial implementation of specification‑driven, recursive refinement methodology is feasible in R using the toolchain and patterns described. The implementation excludes static pre‑generation conformance verification but retains:
- Formal structural specifications (S4/R6/interface)
- Physical skeleton–tissue separation with CI‑enforced dependency direction
- Four automated validation gates
- Phase‑based fixed premises via Git tags and renv
For projects where static type checking is required, use TypeScript, Go, or Python with mypy instead of R.