Good point, let’s be more specific. The discussion I think I am having (hope others agree :-) ) is on the points from my previous post here: Stan++/Stan3 Preliminary Design
I’ll try to rephrase it and introduce some terminology to let us stay focused.
Basically the design as proposed (if I understand it correctly) features what I’d call implicit binding: unbound data variables from a fragment/submodel somehow magically bubble up to the top level and are treated as data to the main model, while everything inside the fragment is visible to the outside world e.g.:
fragment gaussian_process {
data int N;
data vector[N] x;
...
vector[N] y_raw ~ normal(0,1);
vector[N] y = <<cholesky and GP stuff>>
}
fragment gp = gaussian_process();
//now both gp.y and gp.y_raw can referenced
There were two variants floated around, one in which the main model automatically gains data gp.x
and gp.N
, and another where the main model gets data x
and N
. In both cases this is automagic.
I am trying to argue for explicit binding, where fragments/submodels have explicit interface, both in (as arguments to instantiation) and out (clearly stated which internal parameters/transformed parameters/gen quants are visible to the main model), e.g.:
data int whatever_I_call_it;
data vector[whatever_I_call_it] my_x;
fragment gaussian_process(int N, vector x) {
//Introducing new data variables here is syntax error, only params/gen quants allowed
vector[N] y_raw ~ normal(0,1);
public vector[N] y = <<cholesky and GP stuff>>
}
fragment gp = gaussian_process(whatever_I_call_it, my_x);
//only gp.y can be referenced
Obviously the question about explicit/implicit input is mostly orthogonal to explicit/implicit inner member access.
The argument for implicit binding seems to be - at leat in part - that it is less verbose and less demanding of beginners. I took Elm as a counterexample where everything is explicit, but still it is terse and relatively easy to learn. I also like focusing more on debugging experience than on code writing experience as I believe debugging is more often the bottleneck.
I don’t want to steal a lot from Elm (Stan definitely should not switch to functional), but as for the size - I’ve certainly written programs one or two orders of magnitude larger in Elm than in Stan and I’ve seldom felt it is too verbose.