This vignette gives a brief, combined example of two
ast2ast features: functions defined inside the
translated function (fn), and user-defined struct types
(new_type). See the “Detailed Documentation” vignette for
the full reference.
A custom type is declared in a types_f helper and passed
to translate() via types_f =. Each slot gets a
type via type():
types_f <- function() {
new_type(Point, slots(x |> type(double), y |> type(double)))
}
On the R side, a value of this type is a named list with a matching
class attribute:
structure(list(x = 1, y = 2), class = "Point").
fn() defines a function local to f. It
takes three positional parts: argtypes(...) (argument
types), return(...) (return type), and a { }
block (the function body). The outer function declares its own argument
types with argtypes(...) as the first statement of its
body:
f <- function(p, q) {
argtypes(
p |> type(Point),
q |> type(Point)
)
squared_dist <- fn(
argtypes(
a |> type(Point) |> const() |> ref(),
b |> type(Point) |> const() |> ref()
),
return(double),
{
dx <- a$x - b$x
dy <- a$y - b$y
return(dx * dx + dy * dy)
}
)
return(squared_dist(p, q))
}
fcpp <- ast2ast::translate(f, types_f = types_f)
p <- structure(list(x = 0, y = 0), class = "Point")
q <- structure(list(x = 3, y = 4), class = "Point")
fcpp(p, q) # 25
Inner functions may call each other (including recursively) and can
be passed as values to functions expecting a function argument:
uniroot(), the functionals map(),
Reduce(), Filter(), apply(), and
the optimizers jacobian(), lbfgsb(),
pso(). Struct fields are read and written with
$, and a slot can itself be a custom type or a
collection(TypeName) (a vector of a custom type), enabling
nested structs and vectors of structs.