ModelicaSpecification
ModelicaSpecification copied to clipboard
Modifiability in the context of record constructors
12.6 says:
Component declarations which do not allow a modification (such as final parameter Real) are declared as protected components in the record constructor function.
The obvious starting point to find out what this means would be 7.2 (Modifications), which doesn't say anything about it but contains some non-normative text which points to 4.7 (Balanced Models):
In a declaration of a component of a record, connector, or simple type, modifiers can be applied to any element, and these are also considered for the equation count.
Since 12.6 implies that there are actually components which can't be modified in a record I'm assuming the rule in 4.7 is a bit too permissive. But the rules for what can and can't be modified are spread far and wide and sometimes seems conflicting. E.g. 3.8.1 says constants can be modified after being given a value, while 4.4.4 has non-normative text saying that constants can usually not be changed after being given a value.
Given what I can find it seems like the only components that do not allow a modification in a record would be final or protected components, regardless of variability. Or have I missed something? In that case it would be good to mention that in 12.6 rather than giving a not very helpful example. If the rules are actually more complicated than that it would be good with a reference to those rules though.
The next rule in 12.6 says:
Prefixes (constant, parameter, final, discrete, …) of the remaining record components are removed.
Does this mean that there are actually cases where final
components can be modified in records? Seems odd to list final
in the list of prefixes which are removed otherwise.
Does this mean that there are actually cases where
final
components can be modified in records? Seems odd to listfinal
in the list of prefixes which are removed otherwise.
I think this was just an oversight when it was added in Modelica 2.0; and I can see no discussion explaining why from that time (I cannot find the minutes from meeting 28 and 29 either which doesn't help).
Given what I can find it seems like the only components that do not allow a modification in a record would be final or protected components, regardless of variability. Or have I missed something?
It's even simpler: A record may only contain public components https://specification.modelica.org/maint/3.5/class-predefined-types-and-declarations.html#specialized-classes (a record constructor may contain protected components but that is a function - not a record); so the only components that don't allow modification seems to be the final ones, regardless of variability.
Given what I can find it seems like the only components that do not allow a modification in a record would be final or protected components, regardless of variability. Or have I missed something?
It's even simpler: A record may only contain public components https://specification.modelica.org/maint/3.5/class-predefined-types-and-declarations.html#specialized-classes (a record constructor may contain protected components but that is a function - not a record); so the only components that don't allow modification seems to be the final ones, regardless of variability.
Both Dymola and OpenModelica seems to think that constants with bindings are not allowed to be modified either though, but I can't find any rules in the specification that says that's the case. I.e. both fail on a model like this:
model M
record R
constant Integer n = 1;
end R;
R r = R(2);
end M;
Both Dymola and OpenModelica seems to think that constants with bindings are not allowed to be modified either though, but I can't find any rules in the specification that says that's the case. I.e. both fail on a model like this:
Yes, 12.6 (https://specification.modelica.org/maint/3.5/functions.html#record-constructor-functions) is even explicitly listing constant
as one of the things you remove when a record constructor function is derived from the record member declarations, so this should be a valid model.
Both Dymola and OpenModelica seems to think that constants with bindings are not allowed to be modified either though, but I can't find any rules in the specification that says that's the case. I.e. both fail on a model like this:
Yes, 12.6 (https://specification.modelica.org/maint/3.5/functions.html#record-constructor-functions) is even explicitly listing
constant
as one of the things you remove when a record constructor function is derived from the record member declarations, so this should be a valid model.
That rule only applies to components that are allowed to be modified though, i.e. those that become the input parameters of the constructor. If constants with bindings are in fact not allowed to be modified it's the rule before that one that applies, i.e. they just become protected in the constructor.
Given what I can find it seems like the only components that do not allow a modification in a record would be final or protected components, regardless of variability. Or have I missed something?
It's even simpler: A record may only contain public components https://specification.modelica.org/maint/3.5/class-predefined-types-and-declarations.html#specialized-classes (a record constructor may contain protected components but that is a function - not a record); so the only components that don't allow modification seems to be the final ones, regardless of variability.
Both Dymola and OpenModelica seems to think that constants with bindings are not allowed to be modified either though, but I can't find any rules in the specification that says that's the case. I.e. both fail on a model like this:
The likely cause for both this and the unclarity of constant in this section is that the definition of constant have changed back forth and bit, and this section was likely not updated for that.
I don't know how much that has been used in practice, if used one possibility would be to standarize current tool behavior just to avoid breaking things; and don't rely on the implicit "changeable".
I don't know how much that has been used in practice, if used one possibility would be to standarize current tool behavior just to avoid breaking things; and don't rely on the implicit "changeable".
I tried removing the check for constants with bindings in OpenModelica and only check for final
, and at least the MSL worked fine. I can make a wider test on all the libraries we test, but that'll take more time.
Proposals to improve:
Component declarations which do not allow a modification (such as final parameter Real) are declared as protected components in the record constructor function.
One of:
- Component declarations that are final or constant are declared as protected components in the record constructor function.
- Component declarations that are final (and thus do not allow a modification) are declared as protected components in the record constructor function. Either is clearer than what we currently have. The first correspond to existing implementations.
I tried to see if there are any records with constants in MSL:
They exist in particular for Modelica.Electrical.Batteries.ParameterRecords and it seems that the current implementations not having the constants in the record constructors is the intent for these.
Similarly Modelica.Electrical.Spice3.Internal.ModelcardBJT2 and Modelica.Electrical.Spice3.Internal.ModelcardMOS use constant for things that shouldn't be changed.
Since the record constructor calls normally use named arguments allowing modifications will not break existing models, but it will break the intent of the models (of hiding constants).
Note: Seems that both variants would work with existing use in MSL (the constants are not set in the calls).
Note: Seems that both variants would work with existing use in MSL (the constants are not set in the calls).
However, I believe that the intent is that users don't change the constants in the constructor-calls. Clearly they could have been set as final
to clarify that.
I believe it's simplest to poll for this change.
The two options are (just select the smiley to choose an emoji).
- 🚀 (rocket) Component declarations that are final or constant are declared as protected components in the record constructor function.
- 👀 (eyes) Component declarations that are final (and thus do not allow a modification) are declared as protected components in the record constructor function.
Running the poll until end of July so that everyone has time to vote.
To count as informative, I think a poll like this needs to be announced on the email list – I'm afraid there are generally too many GitHub notifications for most people to actually pay attention to their content.
To count as informative, I think a poll like this needs to be announced on the email list – I'm afraid there are generally too many GitHub notifications for most people to actually pay attention to their content.
Even if that would be ideal, I see that the result of the poll was clear, i.e.: "Component declarations that are final (and thus do not allow a modification) are declared as protected components in the record constructor function."