On Mon, 27 Mar 2023 at 05:17, Gaius Mulley wrote:
here is a further example using the <* bytealignment(0) *> attribute
(for non SET types):
Small_Set_T = PACKEDSET OF [0..7] ;
bar = ARRAY [0..7] OF BOOLEAN <* bytealignment(0) *> ;
Using language syntax should be reserved for features that have semantic impact, while pragmas should be used for features that merely influence the compilation process without changing the semantics. Controlling alignment does not alter the semantics, it is merely an optimisation. It should therefore always be done by pragma, not by language syntax.
Very unfortunately, PACKEDSET is one of those things ISO M2 inherited from WG13, the sum of which then messed up the entire standard leading to a bloated and inconsistent design. It is thus understandable that you wanted to keep the feature around, just so as to satisfy the standard specification.
However, it does introduce yet another inconsistency when the alignment pragma won't apply to SET types. It would be more consistent to simply allow the alignment pragma to also be used with SET types in effect becoming a PACKEDSET. Although this violates the principle that there should ideally be only one single syntax for every feature, one has to ask the question, which is worse: The inconsistency/non-orthogonality or the violation of the single-syntax principle?
In my view, consistency and orthogonality is far more important and in order to preserve it, a violation of the single-syntax principle is the lesser evil in this particular case.
Furthermore, when GM2 is used in PIM mode, there is no PACKEDSET type constructor, but the pragma should still be available.
I therefore encourage you to allow the alignment pragma to be used with the SET constructor in both PIM and ISO mode.
I also encourage you to implement the pragma convention in our revised M2 specification:
Note this is a reduced pragma set for the bootstrap specification which lacks the alignment pragma. In the complete set, the alignment pragma symbol is ALIGN. For any implementation specific pragmas, there should be a compiler identifier preceding the pragma symbol, thus
TYPE FooSet = SET OF [0..7] <*ALIGN=1*>;
GM2 specific pragma:
TYPE FooSet = SET OF [0..7] <*gm2.bytealignment(0)|WARN*>;
The idea here is that a compiler can always identify whether any given pragma is intended for it or not, and what to do if a pragma is found that is specific to another compiler. This way, the facility becomes portable even for unknown pragmas, which is possible precisely because pragmas do not change semantics, but only optimisations (in the widest sense).