Hello,
It seems as though it would be good to discuss the evaluation rules for the Dynare 5 language on the list before going too far with the prototype. To animate this discussion, a simple series of commands in the new language would be useful:
a <- 1; b <- a + 1; a <- 2;
model { endogenous c; ...
equations { b = c*...; ... } }
Basically, we need to determine how to evaluate b in this situation:
1) In the statement, b <- a + 1;, should b be evaluated to hold the value 2 or should it hold the symbolic value "a + 1"? 1a) If the answer is 2, should we allow for symbolic storage as well? I.e., the user could write something of the form: b <- sym(a) + 1; if they wanted to store the symbolic value "a + 1"? 1b) If the answer is "a + 1", should we allow for some type of forced evaluation notion to make b take the value 2? I.e., something of the form b <- eval(a) + 1;? NB: We could replace sym and eval by whatever we wanted (some languages use a preceding $ sign or quote). The idea here is mainly to decide the functionality we want to support (i.e. both 1a and 1b or just one or the other) as well as the default functionality (either 1a or 1b), but if people have strong preferences for/against a certain delimiter, they should be stated.
2) In model-related blocks (model, calibration, initval, etc), should b in this case evaluate to 2, "a+1" or 3? 2a) If 2, this means that 1a from above holds 2b) If "a+1" this means that 1b from above holds 2c) If 3, this means that 1b from above holds but that, in model-type blocks, programming variables are evaluated by default (ie, b has the value "a+1" until it is used, at which point the last available value of a is looked up, in this case 2, and b is evaluated giving 3) NB: as above, we need to decide what the default behavior will be, whether or not we will enable all behaviors listed or others I missed, and, if enabling all behaviors, what delimiters we will use to do so (e.g. $, ', eval(), etc)
3) Finally, we must decide whether to support model variable names that overlap with programming variable names. For example, in this case, would it be ok to have endogenous a; or endogenous b;? Maybe it will lead to bugs in people's code to have this option. At the same time, since we're asking users to keep track of different types of variables in their mod files (i.e. programming variables versus model variables) as well as the scope of those variables (for loops for example) it seems quite natural to support this feature.
Best, Houtan
Houtan Bastani houtan.bastani@ens.fr writes:
It seems as though it would be good to discuss the evaluation rules for the Dynare 5 language on the list before going too far with the prototype. To animate this discussion, a simple series of commands in the new language would be useful:
a <- 1; b <- a + 1; a <- 2;
model { endogenous c; ...
equations { b = c*...; ... } }
Basically, we need to determine how to evaluate b in this situation:
- In the statement, b <- a + 1;, should b be evaluated to hold the value 2 or should it hold the symbolic value "a + 1"?
I’d say 2.
1a) If the answer is 2, should we allow for symbolic storage as well? I.e., the user could write something of the form: b <- sym(a) + 1; if they wanted to store the symbolic value "a + 1"?
Yes, something like that (maybe with a nicer syntax, possibly a single character quoting operator).
- In model-related blocks (model, calibration, initval, etc), should b in this case evaluate to 2, "a+1" or 3?
2a) If 2, this means that 1a from above holds 2b) If "a+1" this means that 1b from above holds 2c) If 3, this means that 1b from above holds but that, in model-type blocks, programming variables are evaluated by default (ie, b has the value "a+1" until it is used, at which point the last available value of a is looked up, in this case 2, and b is evaluated giving 3) NB: as above, we need to decide what the default behavior will be, whether or not we will enable all behaviors listed or others I missed, and, if enabling all behaviors, what delimiters we will use to do so (e.g. $, ', eval(), etc)
None of the above: it should remain as "b". And we should add an operator to force evaluation of b, which would in that case be replaced by its value, which is 2 according to the previous rule.
- Finally, we must decide whether to support model variable names
that overlap with programming variable names. For example, in this case, would it be ok to have endogenous a; or endogenous b;? Maybe it will lead to bugs in people's code to have this option. At the same time, since we're asking users to keep track of different types of variables in their mod files (i.e. programming variables versus model variables) as well as the scope of those variables (for loops for example) it seems quite natural to support this feature.
I think there is some confusion here. You are mixing the symbol (which is a string of characters) with its assigned value (in some evaluation environment). A symbol by itself is neither a programming variable nor a model variable. This is something that will change from Dynare 4 where currently a symbol is always of a given type; I think we should drop that rule.
Then you have evaluation environments that maps symbols to their values: these environments are only meaningful in a programming context; they are not relevant within a model context (except during the declaration of the model, where you could use programming features, possibly forcing evaluation with the associated operator).
Maybe I could summarize my previous post by the following rules:
* everywhere except in the list of equations of a model, evaluation should always be triggered, except otherwise specified (with a sym()-like operator)
* in the list of equations of a model, evaluation should never be triggered, except otherwise specified (with an eval()-like operator)
And I would add a 3rd rule:
* when trying to evaluate a symbol, if it is not assigned, then trigger an error. This means that it is ok to use an unassigned symbol in the equations list of a model, but not outside (unless the sym() operator is used)
OK, by me
Michel
On 04/18/2012 04:16 PM, Sébastien Villemot wrote:
Maybe I could summarize my previous post by the following rules:
everywhere except in the list of equations of a model, evaluation should always be triggered, except otherwise specified (with a sym()-like operator)
in the list of equations of a model, evaluation should never be triggered, except otherwise specified (with an eval()-like operator)
And I would add a 3rd rule:
- when trying to evaluate a symbol, if it is not assigned, then trigger an error. This means that it is ok to use an unassigned symbol in the equations list of a model, but not outside (unless the sym() operator is used)
Dev mailing list Dev@dynare.org https://www.dynare.org/cgi-bin/mailman/listinfo/dev
Looks OK for me, too. I have only one thing to add. As I dont know the design of Dynare 5 very well, I dont know if it applies. But one of the common problems for users of Dynare 4 was that model parameters are regularly defined in a recursive manner before the model block. Automatic evaluation was no problem as long as the model was only solved once. Problems started when people then wanted to estimate some of the parameters, but the recursive dependence of subsequent (non-estimated) parameters was not taken into account. You had to use the #-operator inside of the model-block to circumvent this issue. But there was no way to do this outside of the model block except for the steady state file.
Hence, I think it should be made easier to specify dependencies like this outside of the model block. Defining a sym-operator outside of the model block seems a suitable way to achieve this.
However,
b <- sym(a) + 1;
seems like strange syntax. One wants b to be treated as a symbol, not a. Hence, implicitly defining b as a symbol by typecasting might be too complicated for non-programmers. I would prefer something along the lines of the old #-operator like:
sym(b) <- a + 1;
Best, Johannes
Von: dev-bounces@dynare.org [mailto:dev-bounces@dynare.org] Im Auftrag von Michel Juillard Gesendet: Mittwoch, 18. April 2012 16:21 An: List for Dynare developers Betreff: Re: [DynareDev] Dynare 5 Preprocessor Evaluation Rules
OK, by me
Michel
On 04/18/2012 04:16 PM, Sébastien Villemot wrote:
Maybe I could summarize my previous post by the following rules:
* everywhere except in the list of equations of a model, evaluation should always be triggered, except otherwise specified (with a sym()-like operator)
* in the list of equations of a model, evaluation should never be triggered, except otherwise specified (with an eval()-like operator)
And I would add a 3rd rule:
* when trying to evaluate a symbol, if it is not assigned, then trigger an error. This means that it is ok to use an unassigned symbol in the equations list of a model, but not outside (unless the sym() operator is used)
_______________________________________________ Dev mailing list Dev@dynare.org https://www.dynare.org/cgi-bin/mailman/listinfo/dev
Those rules are fine.
On 18 Apr 2012, at 16:08, Sébastien Villemot wrote:
I think there is some confusion here. You are mixing the symbol (which is a string of characters) with its assigned value (in some evaluation environment). A symbol by itself is neither a programming variable nor a model variable. This is something that will change from Dynare 4 where currently a symbol is always of a given type; I think we should drop that rule.
Then you have evaluation environments that maps symbols to their values: these environments are only meaningful in a programming context; they are not relevant within a model context (except during the declaration of the model, where you could use programming features, possibly forcing evaluation with the associated operator).
So, this means it is OK to have symbols that take on different values in different scopes. Ie in:
co <- "abc" countries <- {US JA FR}
for (co in countries) { ... }
would be valid code and co would take the values of countries within the scope of the for loop and "abc" both before and after the loop.
Best, Houtan
Houtan Bastani houtan.bastani@ens.fr writes:
So, this means it is OK to have symbols that take on different values in different scopes. Ie in:
co <- "abc" countries <- {US JA FR}
for (co in countries) { ... }
would be valid code and co would take the values of countries within the scope of the for loop and "abc" both before and after the loop.
In this context it is debatable. In some languages like C, co would be restored to "abc" after the loop; but not in R for example.
The question is whether a "for" loop pushes a new environment on the environment stack containing only one variable (the indexing variable).
I think that it is simpler if we consider that a for loop does not create a new environment, and therefore that in your example co is equal to "FR" after the loop.
To make our language simple, I think only function calls should push new environments on the environment stack (like R does).
On 18 Apr 2012, at 17:27, Sébastien Villemot wrote:
In this context it is debatable. In some languages like C, co would be restored to "abc" after the loop; but not in R for example.
The question is whether a "for" loop pushes a new environment on the environment stack containing only one variable (the indexing variable).
I think that it is simpler if we consider that a for loop does not create a new environment, and therefore that in your example co is equal to "FR" after the loop.
To make our language simple, I think only function calls should push new environments on the environment stack (like R does).
So, then, no new scope within a model block and hence no model variables with the same names as programming variables.
Houtan Bastani houtanb@gmail.com writes:
On 18 Apr 2012, at 17:27, Sébastien Villemot wrote:
In this context it is debatable. In some languages like C, co would be restored to "abc" after the loop; but not in R for example.
The question is whether a "for" loop pushes a new environment on the environment stack containing only one variable (the indexing variable).
I think that it is simpler if we consider that a for loop does not create a new environment, and therefore that in your example co is equal to "FR" after the loop.
To make our language simple, I think only function calls should push new environments on the environment stack (like R does).
So, then, no new scope within a model block and hence no model variables with the same names as programming variables.
It is possible to have the same symbol referring to both a programming variable and to a model variable, as in the first example that you sent on the list.