## 6.11 Higher-order functions

There are several expression constructions in Stan that act as higher-order functions.4

The higher-order functions and the signature of their argument functions are listed in the higher-order functions table and the variadic higher-order functions table.

Higher-order Functions Table. Higher-order functions in Stan with their argument function types. The first group of arguments can be a function of parameters or data. The second group of arguments, consisting of a real and integer array in all cases, must be expressions involving only data and literals.

function parameter or data args data args return type
algebra_solver vector, vector array [] real, array [] real vector
algebra_solver_newton vector, vector array [] real, array [] real vector
integrate_1d, real, real, array [] real array [] real, array [] real real
integrate_ode_X, real, array [] real, array [] real array [] real, array [] real array [] real
map_rect vector, vector array [] real, array [] real vector

For example, the integrate_ode_rk45 function can be used to integrate differential equations in Stan:

functions {
array [] real foo(real t,
array [] real y,
array [] real theta,
array [] real x_r,
array [] real x_i) {
// ...
}
}
// ...
int<lower=1> T;
array real y0;
real t0;
array[T] real ts;
array real theta;
array real x_r;
array int x_i;
// ...
array[T, 2] real y_hat = integrate_ode_rk45(foo, y0, t0,
ts, theta, x_r, x_i);

The function argument is foo, the name of the user-defined function; as shown in the higher-order functions table, integrate_ode_rk45 takes a real array, a real, three more real arrays, and an integer array as arguments and returns 2D real array.

Variadic Higher-order Functions Table. Variadic Higher-order functions in Stan with their argument function types. The first group of arguments are restricted in type. The sequence of trailing arguments can be of any length with any types.

function restricted args return type
ode_X, vector, real, array [] real vector[]
reduce_sum array[] T, T1, T2 real

T, T1, and T2 can be any Stan type.

For example, the ode_rk45 function can be used to integrate differential equations in Stan:

functions {
vector foo(real t, vector y, real theta, vector beta,
array [] real x_i, int index) {
// ...
}
}
// ...
int<lower=1> T;
vector y0;
real t0;
array[T] real ts;
real theta;
vector beta;
array int x_i;
int index;
// ...
vector y_hat[T] = ode_rk45(foo, y0, t0, ts, theta,
beta, x_i, index);

The function argument is foo, the name of the user-defined function. As shown in the variadic higher-order functions table, ode_rk45 takes a real, a vector, a real, a real array, and a sequence of arguments whos types match those at the end of foo and returns an array of vectors.

### Functions passed by reference

The function argument to higher-order functions is always passed as the first argument. This function argument must be provided as the name of a user-defined or built-in function. No quotes are necessary.

### Data-restricted arguments

Some of the arguments to higher-order functions are restricted to data. This means they must be expressions containing only data variables, transformed data variables, or literals; the may contain arbitrary functions applied to data variables or literals, but must not contain parameters, transformed parameters, or local variables from any block other than transformed data.

For user-defined functions the qualifier data may be prepended to the type to restrict the argument to data-only variables.

1. Internally, they are implemented as their own expression types because Stan doesn’t have object-level functional types (yet).↩︎