Skip to main content

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

  1. Rename one .R file to .infr
  2. Run infr check — should produce zero errors
  3. Add const to bindings that shouldn't change
  4. Add type annotations to function signatures
  5. Run infr build to emit clean .R for production

Your R scripts, packages, and workflows stay the same. Infr works alongside existing R infrastructure.

Key differences from R

FeatureRInfr
File extension.R.infr (transpiles to .R)
Variable binding<- onlyconst, let, or <-
Type annotationsNoneOptional : type syntax
Type checkingRuntime errorsCompile-time diagnostics
Function return typesImplicitOptional -> type syntax
Null safetyRuntime NULL errorsT? 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