# Stan functions exported to R: how do argument type conversions work?

**URL:** <https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620>\
**Category:** RStan\
**Tags:** rstan\
**Created:** [September 29, 2021, 2:28pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620 "2021-09-29T14:28:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jtimonen](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jtimonen/32/9034_2.png) [@jtimonen](https://discourse.mc-stan.org/u/jtimonen)\
**Post date:** [September 29, 2021, 2:28pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620/1 "2021-09-29T14:28:05Z")

</div>

When using `rstan::expose_stan_functions()`, functions defined in the `functions` block of Stan code get exported to R. My question is that **are there some rules to determine what the R type of the function arguments should be given the Stan type?** This is difficult to know with multidimensional arrays (or arrays of vectors/matrices). Sometimes the first dimension of an array has be encoded using a list in R. For one-dimensional arrays of reals apparently not. So far I have only tried to infer the types by trial and error but it is slow because error messages are not very informative, like:

```
VECTOR_ELT() can only be applied to a 'list', not a 'double'

```

---

<div class="post-metadata">

**Author:** ![jtimonen](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jtimonen/32/9034_2.png) [@jtimonen](https://discourse.mc-stan.org/u/jtimonen)\
**Post date:** [September 29, 2021, 2:56pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620/2 "2021-09-29T14:56:06Z")

</div>

Like currently I have the above message, but I have several arguments and I have no information which one of them is the one that is in wrong format. There is this small discussion [Rstan error: VECTOR\_ELT() can only be applied to a 'list', not a 'double'](https://discourse.mc-stan.org/t/rstan-error-vector-elt-can-only-be-applied-to-a-list-not-a-double/2093) it focuses only on one specific case

---

<div class="post-metadata">

**Author:** ![andrjohns](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/andrjohns/32/15297_2.png) [@andrjohns](https://discourse.mc-stan.org/u/andrjohns)\
**Post date:** [September 29, 2021, 3:08pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620/3 "2021-09-29T15:08:04Z")

</div>

The mapping is `numeric`/`integer` scalars for `int` and `real` types, `numeric` vectors for `vector` and `real[]` types, `matrix` for `matrix`, and `lists` of the above for any arrays of containers.

We can verify this with a toy example. First, a functions block that just returns the input argument for a variety of types:

```r
test_fun = "

functions {

real real_tester(real real_arg) {
 return real_arg;            
}

int int_tester(int int_arg) {
 return int_arg;            
}

vector vector_tester(vector vector_arg) {
 return vector_arg;            
}

real[] real_array_tester(real[] real_array_arg) {
 return real_array_arg;            
}

matrix matrix_tester(matrix matrix_arg) {
 return matrix_arg;            
}

vector[] vector_array_tester(vector[] vector_array_arg) {
 return vector_array_arg;            
}

matrix[] matrix_array_tester(matrix[] matrix_array_arg) {
 return matrix_array_arg;            
}

matrix[,] nested_matrix_array_tester(matrix[,] nested_matrix_array_arg) {
 return nested_matrix_array_arg;            
}
}
"

```

Next, we just the input arguments of the correct type to verify that all works:

```r
> real_tester(1)
[1] 1
> int_tester(1)
[1] 1
> vector_tester(1:3)
[1] 1 2 3
> real_array_tester(1:3)
[1] 1 2 3
> matrix_tester(matrix(1:6,ncol=3,nrow=2))
     [,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> vector_array_tester(list(1:3,4:7))
[[1]]
[1] 1 2 3

[[2]]
[1] 4 5 6 7

> matrix_array_tester(list(matrix(1:6,ncol=3,nrow=2),
+ matrix(7:10,ncol=2,nrow=2)))
[[1]]
     [,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6

[[2]]
     [,1] [,2]
[1,] 7 9
[2,] 8 10

> nested_matrix_array_tester(
+ list(
+ list(matrix(1:6,ncol=3,nrow=2),matrix(7:10,ncol=2,nrow=2)),
+ list(matrix(1:4,ncol=2,nrow=2),matrix(5:10,ncol=2,nrow=3))
+ )
+ )
[[1]]
[[1]][[1]]
     [,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6

[[1]][[2]]
     [,1] [,2]
[1,] 7 9
[2,] 8 10

[[2]]
[[2]][[1]]
     [,1] [,2]
[1,] 1 3
[2,] 2 4

[[2]][[2]]
     [,1] [,2]
[1,] 5 8
[2,] 6 9
[3,] 7 10

```

---

<div class="post-metadata">

**Author:** ![andrjohns](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/andrjohns/32/15297_2.png) [@andrjohns](https://discourse.mc-stan.org/u/andrjohns)\
**Post date:** [September 29, 2021, 3:09pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620/4 "2021-09-29T15:09:20Z")

</div>

Also, if this relates to the standalone functions for your `lgpr` package, I have updates to `rstantools` in the pipeline for automatically generating the exports for standalone functions. So you won’t need to manually generate/modify these in future

---

<div class="post-metadata">

**Author:** ![jtimonen](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jtimonen/32/9034_2.png) [@jtimonen](https://discourse.mc-stan.org/u/jtimonen)\
**Post date:** [September 29, 2021, 3:18pm UTC](https://discourse.mc-stan.org/t/stan-functions-exported-to-r-how-do-argument-type-conversions-work/24620/5 "2021-09-29T15:18:57Z")

</div>

Yes it relates to that and other similar development. The only ‘manual’ thing that I currently have to do is to run this script [lgpr/cpp.R at master · jtimonen/lgpr · GitHub](https://github.com/jtimonen/lgpr/blob/master/dev/cpp.R) to get the export, so that is not the slow part. But of course it would be better if it was done by rstantools. The bigger problem has  
been not knowing how to call the exported functions, but now it should be clear since you explained it.
