Confused about #includes

I was trying to figure out how #include statements work. I’m using rstan 2.21.3, but I consulted the most recent documentation as well. I diffed the relevant sections of the Stan User’s Guide for 2.21 and 2.28 2_28 includes and they differ only in trivial ways. I’m following the examples in the text.

Suppose I have a model that defines a function, but I also wish to include some shared functions by using an #include statement.

I can’t have two functions blocks, so the #included file must only consist of the bare function definition, so in my-std-normal-stan I have this:

  real included_my_std_normal_lpdf(real y) {
    return -0.5 * y' * y;
  }

and in my main file I have this:

functions {
  #include my-std-normal.stan
  real defined_here_my_std_normal_lpdf(real y) {
    return -0.5 * y' * y;
  }
}
parameters {
  real y;
}
model {
  y ~ defined_here_my_std_normal();
  y ~ included_my_std_normal();
}

However, when checking the syntax, or when compiling the model with a call to stan_model(), I get the following error:

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Probability function must end in _lpdf or _lpmf. Found distribution family = included_my_std_normal with no corresponding probability function included_my_std_normal_lpdf, included_my_std_normal_lpmf, or included_my_std_normal_log
 error in 'model3cc26a57f781_expt_function_defs' at line 13, column 31
  -------------------------------------------------
    11: model {
    12:   y ~ defined_here_my_std_normal();
    13:   y ~ included_my_std_normal();
                                      ^
    14: }
  -------------------------------------------------

Error in stanc(filename, allow_undefined = TRUE) : 
  failed to parse Stan model 'expt_function_defs' due to the above error.

On the other hand, if I remove the #include statement and substitute the function definition it compiles fine. And if I remove the indentation before the #include it works fine; that contradicts section 2.01 in both versions of the manual, which says that whitespace is allowed before #includes.

It seems there was a lot of discussion about this in 2017, but it’s not clear to me what the final outcome was. Here’s the link: https://discourse.mc-stan.org/t/syntax-and-scope-for-stan-language-includes/239.

Finally, the code in version 2_21 doesn’t compile for another reason, a type mismatch: In the documentation, the function definition declares y as a vector, but in the parameters block as a real. Is this different in rstan 2_26? The documentation for 2_26 is the same.

functions {
  real my_std_normal_lpdf(vector y) {
    return -0.5 * y' * y;
  }
}
parameters {
  real y;
}
model {
  y ~ my_std_normal();
}
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
No matches for: 

  real ~ my_std_normal()

Available argument signatures for my_std_normal:

  vector ~ my_std_normal()

Real return type required for probability function.
 error in 'model3cc2bc40ed1_expt_3function_defs' at line 10, column 22
  -------------------------------------------------
     8: }
     9: model {
    10:   y ~ my_std_normal();
                             ^
    11: }
  -------------------------------------------------

Error in stanc(filename, allow_undefined = TRUE) : 
  failed to parse Stan model 'expt_3function_defs' due to the above error.

Thanks

EDIT: @maxbiostat edited this post for syntax highlighting.

3 Likes