Overview

ast2ast follows R wherever possible. A few things work differently because the generated C++ is statically typed:

No access to the enclosing environment

A translated function only sees its arguments and its own variables. Everything else has to be passed as an argument.

k <- 2
f <- function(x) {
  argtypes(x |> type(vec(double)))
  return(x * k)
}
translate(f)
# return(x * k)
# Found uninitialized variable: k

Fix: pass k as argument.

f <- function(x, k) {
  argtypes(
    x |> type(vec(double)),
    k |> type(double)
  )
  return(x * k)
}

No recycling

Both operands must have the same length, or one of them must be a scalar. R would recycle the shorter vector.

f <- function() {
  return(c(1, 2, 3, 4) + c(10, 20))
}
fcpp <- translate(f)
fcpp()
# In 'return(c(1.0, 2.0, 3.0, 4.0) + c(10.0, 20.0))': encountered non-conformable arrays

Fix: build the vector with the full length, e.g. rep(c(10, 20), 2L).

Integer arguments

An argument of type int only accepts integers. A double is not converted.

f <- function(n) {
  argtypes(n |> type(int))
  return(n + 1L)
}
fcpp <- translate(f)
fcpp(200)
# Type mismatch for 'n': expected integer, got double
fcpp(200L)
# [1] 201

The same holds inside f: a bare 1 is a double. Use 1L or 1L:3L for integers.

Integer sum

Integer overflow gives NA with a warning, as in R. Only sum() differs: R returns a double if the sum of an integer vector does not fit into an integer. In ast2ast the type is fixed at translation time, so the result is NA with a warning.

f <- function(x) {
  argtypes(x |> type(vec(int)))
  return(sum(x))
}
translate(f)(c(.Machine$integer.max, 1L))
# [1] NA
# Warning: integer overflow - use sum(as.numeric(.))

Inf, NaN and NA

A bare Inf or NaN as a scalar is rejected. Wrap the value in c():

f <- function() {
  y <- -Inf
  return(y)
}
translate(f)
# Found unallowed base type Inf, for the variable y

f <- function() {
  y <- c(-Inf)
  z <- c(1, Inf, NaN, NA)
  return(z)
}
translate(f)()
# [1]   1 Inf NaN  NA

As in R, c(NA) alone is logical; together with a double it becomes a double NA.