Coming from R
If you're an R programmer, Infr is designed to feel immediately familiar. Every valid R program is already a valid Infr program. This page highlights what Infr adds and how to adopt it incrementally.
Nothing changes until you want it to
Rename script.R to script.infr and run infr check script.infr. If your R code is valid, Infr will produce zero errors. That's the starting point.
From there, you can add types and const bindings one at a time. There's no "all or nothing" — each annotation you add gives you more safety without affecting the rest of your code.
What Infr adds to R
const and let bindings
R has no way to prevent reassignment. Infr adds const:
const DATA_PATH <- "data/input.csv"
DATA_PATH <- "other.csv"
# Error [infr]: Cannot reassign const binding `DATA_PATH`
Use let when you intend to reassign:
let counter <- 0
counter <- counter + 1 # OK
Plain <- still works exactly as it does in R — it's treated as mutable.
Type annotations
Add types after variable names with :, and return types with ->:
const x: numeric <- 5
const name: character <- "Alice"
add <- function(x: numeric, y: numeric) -> numeric {
x + y
}
Infr infers types wherever possible, so annotations are optional. Add them where they help with clarity or where inference can't reach (function parameters).
Nullable types
find_user <- function(id: integer) -> character? {
if (id > 100) NULL
else "Alice"
}
const user <- find_user(5L) # type: character?
# Infr ensures you check for NULL before using nullable values:
if (!is.null(user)) {
nchar(user) # OK — Infr narrows the type to character
}
The adoption path
- Rename one
.Rfile to.infr - Run
infr check— should produce zero errors - Add
constto bindings that shouldn't change - Add type annotations to function signatures
- Run
infr buildto emit clean.Rfor production
Your R scripts, packages, and workflows stay the same. Infr works alongside existing R infrastructure.
Key differences from R
| Feature | R | Infr |
|---|---|---|
| File extension | .R | .infr (transpiles to .R) |
| Variable binding | <- only | const, let, or <- |
| Type annotations | None | Optional : type syntax |
| Type checking | Runtime errors | Compile-time diagnostics |
| Function return types | Implicit | Optional -> type syntax |
| Null safety | Runtime NULL errors | T? types with narrowing |
What Infr does NOT change
- No new runtime constructs (no classes, modules, or control flow)
- No runtime overhead — transpiled output is plain R
- No changes to how R packages work
- No interference with
source(),library(), or any R tooling - S3/S4/R5 classes work as before