Dear all,
This summer we plan to add the possibility to use sets in the
Dynare macro language. This would allow to write some codes in a more
elegant manner, avoiding the use of more or less complex nested loops.
To initiate the discussion here are some first (unordered) ideas for the
new features and interface to be implemented.
Suppose one wants to write something like:
GDP_US = ...
GDP_FR = ...
GDP_EU = ...
CPI_US = ...
CPI_FR = ...
CPI_EU = ...
With the current implementation of the macroprocessor, this has to be
done with two nested loops. If instead we could define sets and tuples
in the macro language we could do it with one loop using a Cartesian
product of sets for the variables (GDP and CPI) and the coluntries (US,
FR, EU).
We may declare sets using the following syntax:
@#define VARIABLE={"GDP", "CPI"}
@#define COUNTRY={"US", "FR", "EU"}
@#define TOTO={1, 2, 3}
@#define TITI={"A", 3, "C"}
@#define TUTU={(1,1), (1,2), (2,1), (2,2)}
@#define ZERO={}
A set, defined by using opening and closing curly braces, can be
composed of strings (VARIABLE and COUNTRY), integers (TOTO), or tuples
(TUTU). A set can be empty (ZERO), and can contain objects of different
types (not as the arrays). A tuple defined by opening and closing
parenthesis can also contain objects of different types. I am not sure
that we need to create an interface to define tuples.
We need to define operations on these sets
[1] @{VARIABLE}+@{COUNTRY} could be the union of two sets
[2] @{TITI}-@{TOTO} could be the set difference
[3] We could add something for the intersection, but this can be
emulated with the set difference and union: the intersection of sets A
and B is equal to (A+B)-((B-A)+(A-B)).
[4] @{VARIABLE}*@{COUNTRY} could be the Cartesian product of two
sets. This operation returns a set of tuples:
@{VARIABLE}*@{COUNTRY} = {("GDP", "US"), ("GDP", "FR"), ("GDP", "EU"), ("CPI", "FR"), ...}
We should also define calculus rules for these operations (for instance
precedence rules).
And finally, it should be possible to iterate on tuples in a for loop
(to avoid the nested loops). Something like:
@#for (v,c) in TUTU
@{v}_@{c} = ...
@endif
Best,
Stéphane.