Okay. As I said, I see the benefits. I was just surprised when the errors appeared.
On my general point, I think I won’t be the only one who needs to adjust their thinking a little to understand why the Simulations use external parameter names. Here’s how I was previously thinking about it.
When you’re making a model, there’s first a design phase, where you set up all the equations, and then there’s a calibration phase, where you plug in values. For me, set_param!
was very much a “calibration phase” operation, while “connect_param!” is in the design phase. Because of this, I’ll always do all of my connect_param!'s first, and typically split them out in a separate function. Then, each Monte Carlo simulation is just redoing the calibration phase with different values.
When I’m setting values, I might find that I need to construct a unique external parameter name, but I treat this as a technicality. All I’m really trying to do is set a particular parameter in the model.
But now, I think I should redesign my code to be conceptually consistent with the design of Mimi. When designing my model, I should construct all of the external parameter names that I will want to use. Then, during calibration, I should use set_external_param!
and never use set_param!
, because set_param!
breaks an abstraction barrier. If I let people ever use set_param!
, then if I give my model object to some other piece of code, I could find that I can no longer run my Monte Carlo code on it.
An alternative solution, which would be more in-line with the existence of the set_param!
function, is to say that the construction of external parameters is entirely a “calibration” operation, and therefore Monte Carlo simulations should construct their own external parameters if they want to use them. In essence, the lines in the @defsim
should be in the business of calling set_param!
rather than calling set_external_param!
.