Const and Let Bindings
Infr introduces const and let keywords to control variable reassignment — something R has never had.
const — prevent reassignment
const prevents a binding from being reassigned:
const pi_approx <- 3.14159
pi_approx <- 2.0
# Error [infr]: Cannot reassign const binding `pi_approx` (declared at line 1)
const name <- "Alice"
name <- "Bob"
# Error [infr]: Cannot reassign const binding `name` (declared at line 4)
Const is shallow
const prevents rebinding the name, not deep mutation of the underlying object. This matches R's copy-on-modify semantics:
const df <- data.frame(x = 1:3, y = 4:6)
df$z <- 7:9
# Warning [infr]: Mutating const binding `df` via `$<-`.
# This creates a modified copy. Consider using `let` if mutation is intended.
df <- other_df
# Error [infr]: Cannot reassign const binding `df` (declared at line 1)
let — explicit mutability
let declares a binding that you intend to reassign:
let counter <- 0
counter <- counter + 1 # OK
let accumulator <- c()
accumulator <- c(accumulator, new_value) # OK
Plain <- — standard R
The regular <- operator still works exactly as in R. It creates a mutable binding:
x <- 10
x <- 20 # OK — standard R behavior
When to use which?
| Keyword | Use when... |
|---|---|
const | The value should never change (config, constants, final results) |
let | You intend to reassign (counters, accumulators, loop variables) |
<- | Writing standard R code, or not ready to commit to const/let |
Strictness levels
How Infr treats bare <- depends on the strictness level:
| Level | Bare <- behavior |
|---|---|
relaxed (default) | Treated as mutable, no warnings |
moderate | Treated as mutable, warns "consider const or let" |
strict | Error: must use const or let |