Sometime ago I asked the following questions, but got no replies. What about the EP experts out there? ;-)
A question to the EP experts. Are these things allowed?
a) module m; export m = (a => a); const a = 1; end; end.
b) module m; export m = (a => b, a => c); const a = 1; end; end.
c) module m; export m = (a => b, a); const a = 1; end; end.
Likewise for import (assuming m exports a):
a) program p; import m (a => a); begin end.
b) program p; import m (a => b, a => c); begin end.
c) program p; import m (a => b, a); begin end.
Frank
Frank Heckenbach wrote:
Sometime ago I asked the following questions, but got no replies. What about the EP experts out there? ;-)
I'm not sure about the expert part when it comes to EP import and export requirements. However, after spending quite a bit of time peering at those ISO 10206 section and trying to divine their meaning, I think I can take a stab at reasoning out what may or may not be legal constructs in the import and export areas.
I'll note those sections are pretty obtuse and require very careful, close reading while keeping a close eye on the syntax definitions, another close eye on the notational conventions being used, and a third close eye on the general 6.2.2 requirements.
Some points to understanding the workings of export interface regions are:
Note: With interface qualification, there are some additional fine point details which I haven't included.
1. There are both applied and defining occurrences of identifiers in an export interface region. In the case of renaming, the syntax "slot" positions occupied by the applied occurrence and the defining occurrence are distinctly separate positions. Without renaming, both occurrences occupy and coexist in the same syntax "slot" position.
2. Constituent-identifier defining occurrences are the only type of defining occurrence which can be legally created in an export interface region. The syntax definitions do not allow creation any other type of defining occurrence. Thus, the defining occurrence for any other type must be located in some region outside the export interface region.
3. Exportable-name (i.e., constant-name, type-name, etc.) in the syntax definitions and text is making reference to an applied occurrence. From 2 above, it follows that the corresponding defining occurrences for those applied occurrences must be located outside the export interface region. (For the notational conventions used for applied and defining occurrences, see the 6.2.2.11 NOTES.) Also, from the 6.2.2.9 b) define-before-use rule exception, one sees that those defining occurrences must be located in the module-heading region.
4. The rules of 6.2.2.7 and 6.2.2.8 dictate the legally possible combinations of defining and applied occurrence identifiers allowed in an export interface region. An identifier occurrence which contains a defining-point will by 6.2.2.7 rule out any other defining point occurrance with the same identifier spelling and by 6.2.2.8 rule out any other applied occurrence with the same identifier spelling since by 3 above those applied occurrence will fail the "No occurrence outside that scope shall be an applied occurrence." requirement.
A question to the EP experts. Are these things allowed?
a) module m; export m = (a => a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrence which by point 4 above makes the first "a" an illegal construct.
b) module m; export m = (a => b, a => c); const a = 1; end; end.
Legal. Both "a"'s are constant-identifier applied occurrences and no defining occurrence of "a" occurs, the "b" is a constituent-identifier defining occurrence and no other "b" occurs, and the "c" is a constituent-identifier defining occurrence and no other "c" occurs. None of the rules mentioned in point 4 are violated and there is no general rule preventing multiple applied occurrences of an identifier in a region (provided 6.2.2.8 isn't violated). Also, I can't find any specific requirement for export interface regions which prevents exporting the same entity multiple times although 6.2.2.7 and 6.2.2.8 requirements dictate that renaming must be used when multiply exporting the same entity in the same interface.
c) module m; export m = (a => b, a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrance which by point 4 above makes the first "a" an illegal construct.
Likewise for import (assuming m exports a):
Some points to understanding the workings of import interface-specification regions are:
1. Unlike export interface reqions which don't have any enclosed, nested scopes (aside from the interface qualifier quibble), interface-specification regions do enclose other regions for the syntax definition forms with constituent-identifer syntax "slot" positions.
2. In those syntax forms with constituent-identifer regions, each constituent-identifer region has a very narrow scope and each region contains only the defining points for all named interface's constituent-identifers and one specific constituent-identifer applied occurrence (ref. 6.11.3 a)). Thus, all explicitly appearing constituent-identifers have no defining or applied occcurrences in the enclosing interface-specification region. Constituent-identifers as constituent-identifers are confined to constituent-identifer regions which are enclosed by the enclosing interface-specification region. (In import interface-specifications, constituent-identifer scoping works pretty similarly to field-identifier scoping in field-designators, ref. 6.5.3.3)
3. From 2 above and 6.11.3 d) which covers implicitly immported constituent-identifiers, one sees that constituent-identifers as constituent-identifers don't dirty up an interface-specification region with defining or applied constituent-identifer occurrences. An interface-specification region is kept neat and tidy containing only defining occurrences of distinct imported identifiers. Granted some or all of the distinct imported identifiers may have the same spelling as the spelling of a constituent-identifier in the cases of implicitly imported constituent-identifiers and unrenamed explicitly imported constituent-identifiers, but the two identifier bins are isolated from each other.
a) program p; import m (a => a); begin end.
Legal. The first "a" is a constituent-identifer applied occurrence whose defining-point and applied occurrence reside in and are constrained to the narrowly scoped constituent-identifer region which contains just the constituent-identifer "a" occurrence. The second "a" is a distinct imported identifier "a" whose defining point is in the interface-specification region. The 6.2.2.5 scope exclusion rule precludes any 6.2.2.7 and 6.2.2.8 rule violations.
b) program p; import m (a => b, a => c); begin end.
Legal. The first "a" is a constituent-identifer applied occurrence whose defining-point and applied occurrence reside in and are constrained to the narrowly scoped constituent-identifer region which contains just the constituent-identifer "a" occurrence. The second "a" is a constituent-identifer applied occurrence whose defining-point and applied occurrence reside in and are constrained to its own separate, narrowly scoped constituent-identifer region which contains just the second constituent-identifer "a" occurrance. Since the two constituent-identifer regions are distinctly separate regions isolated from each other, no 6.2.2.7 and 6.2.2.8 rule violations can occur.
The "b" and "c" are a distinct imported identifiers whose defining points are in the interface-specification region. There is no requirement that I'm aware of that prevents importing an entity multiple times with unique identifiers for each import. (This seems like a pretty handy feature to have when one needs to repackage interfaces to avoid identifier conflicts.)
c) program p; import m (a => b, a); begin end.
Legal. The first "a" is a constituent-identifer applied occurrence whose defining-point and applied occurrence reside in and are constrained to the narrowly scoped constituent-identifer region which contains just the constituent-identifer "a" occurrence. The second "a" is a constituent-identifer applied occurrence whose defining-point and applied occurrence reside in and are constrained to its own separate, narrowly scoped constituent-identifer region which contains just the second constituent-identifer "a" occurrence. The second "a" is also a distinct imported identifier "a" whose defining point is in the interface-specification region. Since the two constituent-identifer regions are distinctly separate regions and the 6.2.2.5 scope exclusion rule keeps the two constituent-identifer region "a"'s from clashing with the distinct imported identifier "a"in the interface-specification region, there aren't any 6.2.2.7 and 6.2.2.8 rule violations.
Hopefully, I haven't made any mistakes in interpretting ISO 10206 requirements in these areas and that my explanations will help in understanding what may or may not be legal import and export constructs.
P.S. Frank, quite some time ago in the comp.lang.pascal.ansi-iso newsgroup you asked a question about exporting with possibly renaming predefined/required identifiers and I don't think you every got an ISO 10206 based answer. The 6.2.2.9 b) define-before-use rule exception I mentioned in export interface regions point 3 which requires exportable-names to have module-heading region defining-points in conjunction with 6.2.2.10 which conceptually places all but four of the required identifiers in a region enclosing the program is what precludes exporting with possibly renaming all but two of the required identifiers.
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
<snipped general explanations>
I think you missed an important point: interfaces _have to_ brak normal textual scope rules. 6.2.2.2 states that inteface is a separate region outside of the program text -- in particular inteface is a different region then an export list.
Note that 6.11.2 tells us that exportable-name give as defining point in the interface. General rules (especially 6.2.2.7) tell us that the occurence of exportable-name is simultaneously an applied occurence of identifier in export list, which is defined later.
Frank Heckenbach wrote:
A question to the EP experts. Are these things allowed?
a) module m; export m = (a => a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrence which by point 4 above makes the first "a" an illegal construct.
The same analysis would indicate that
module n; export n = (a); const a = 1; end; end.
is illegal. However my reading is that modules `m' and `n' are equivalent. Namely, in both cases we have applied occurence of `a' in the export-list, reffering to the definition of constant `a' and a defining point of `a' in the interface -- since interface and export-list are different regions both can coexist.
c) module m; export m = (a => b, a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrance which by point 4 above makes the first "a" an illegal construct.
Again legal, defining occurences are in the in the interface, applied occurrences are in the export list.
<snipped analysis of imports> I agree.
P.S. Frank, quite some time ago in the comp.lang.pascal.ansi-iso newsgroup you asked a question about exporting with possibly renaming predefined/required identifiers and I don't think you every got an ISO 10206 based answer. The 6.2.2.9 b) define-before-use rule exception I mentioned in export interface regions point 3 which requires exportable-names to have module-heading region defining-points in conjunction with 6.2.2.10 which conceptually places all but four of the required identifiers in a region enclosing the program is what precludes exporting with possibly renaming all but two of the required identifiers.
I think that 6.2.2.9 b) do not forbid anything -- it allows normal case (exporting identifiers declared in module-heading), but just normal rules allows exporting predefined identifiers -- they are already defined when export list is seen, so there is no need to apply 6.2.2.9 b).
Quite some time ago, Waldek Hebisch wrote:
Gale Paeper wrote:
<snipped general explanations>
I think you missed an important point: interfaces _have to_ brak normal textual scope rules. 6.2.2.2 states that inteface is a separate region outside of the program text -- in particular inteface is a different region then an export list.
Note that 6.11.2 tells us that exportable-name give as defining point in the interface. General rules (especially 6.2.2.7) tell us that the occurence of exportable-name is simultaneously an applied occurence of identifier in export list, which is defined later.
Frank Heckenbach wrote:
A question to the EP experts. Are these things allowed?
a) module m; export m = (a => a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrence which by point 4 above makes the first "a" an illegal construct.
The same analysis would indicate that
module n; export n = (a); const a = 1; end; end.
is illegal. However my reading is that modules `m' and `n' are equivalent. Namely, in both cases we have applied occurence of `a' in the export-list, reffering to the definition of constant `a' and a defining point of `a' in the interface -- since interface and export-list are different regions both can coexist.
c) module m; export m = (a => b, a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrance which by point 4 above makes the first "a" an illegal construct.
Again legal, defining occurences are in the in the interface, applied occurrences are in the export list.
Just to be sure before I'll change GPC: Gale, do you agree to Waldek's analyis (i.e., all of my examples should work)?
What about the following case? It's also ok, isn't it? (Exporting b = 1.)
module m; export m = (a => b); const a = 1; b = 2; end; end.
P.S. Frank, quite some time ago in the comp.lang.pascal.ansi-iso newsgroup you asked a question about exporting with possibly renaming predefined/required identifiers and I don't think you every got an ISO 10206 based answer.
There was an answer from John Reagan: "I don't think we intended to allow that. I'd have to look closer at your investigation to find the right words." (news:comp.lang.pascal.ansi-iso, subject "Exporting of predefined identifiers", Feb 2003).
The 6.2.2.9 b) define-before-use rule exception I mentioned in export interface regions point 3 which requires exportable-names to have module-heading region defining-points in conjunction with 6.2.2.10 which conceptually places all but four of the required identifiers in a region enclosing the program is what precludes exporting with possibly renaming all but two of the required identifiers.
I think that 6.2.2.9 b) do not forbid anything -- it allows normal case (exporting identifiers declared in module-heading), but just normal rules allows exporting predefined identifiers -- they are already defined when export list is seen, so there is no need to apply 6.2.2.9 b).
So you (Waldek) mean all predefined identifiers can be exported (and reimported with renaming)? This would allow strange things such as:
Foo (Bar : 42);
(if `Foo' was imported/renamed from `WriteLn'). I hope not. ;-)
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Currently GPC doesn't allow exporting `Input' and `Output', but I think it's not too difficult to change this. Do we agree that this is correct (with and without renaming)?
Frank
Frank Heckenbach wrote:
Quite some time ago, Waldek Hebisch wrote:
Gale Paeper wrote:
<snipped general explanations>
I think you missed an important point: interfaces _have to_ brak normal textual scope rules. 6.2.2.2 states that inteface is a separate region outside of the program text -- in particular inteface is a different region then an export list.
Note that 6.11.2 tells us that exportable-name give as defining point in the interface. General rules (especially 6.2.2.7) tell us that the occurence of exportable-name is simultaneously an applied occurence of identifier in export list, which is defined later.
Frank Heckenbach wrote:
A question to the EP experts. Are these things allowed?
a) module m; export m = (a => a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrence which by point 4 above makes the first "a" an illegal construct.
The same analysis would indicate that
module n; export n = (a); const a = 1; end; end.
is illegal. However my reading is that modules `m' and `n' are equivalent. Namely, in both cases we have applied occurence of `a' in the export-list, reffering to the definition of constant `a' and a defining point of `a' in the interface -- since interface and export-list are different regions both can coexist.
With the exception of a minor quibble about equivalence, I agree with Waldek's analysis.
The quibble is that the constituent-identifier "a" in interface-region "m" in not completely equivalent to the constituent-identifier "a" in interface-region "n". Constituent-identifier "a" in interface-region "m" is not exported as the principal identifier of the value "1"; whereas, constituent-identifier "a" in interface-region "n" is exported as the principal identifier of the value "1".
Note: I haven't fully researched what all the semantic differences are between a principal identifier of value and a non-pricipal identifier. I do note the requirements text takes care to keep the two distinctly separated so I would suppose there is something significant to the difference.
c) module m; export m = (a => b, a); const a = 1; end; end.
Illegal. The first "a" is a constant-identifier applied occurrence whose defining point location is in a region outside the "m" interface region. The second "a" is a constituent-identifier defining occurrance which by point 4 above makes the first "a" an illegal construct.
Again legal, defining occurences are in the in the interface, applied occurrences are in the export list.
Just to be sure before I'll change GPC: Gale, do you agree to Waldek's analyis (i.e., all of my examples should work)?
Yes, I agree Waldek's analysis. (Waldek was also correct in pointing out the basic flaw in my export list example reasoning. I had somehow gotten the mistaken notion that there was some sort of program text linkage between the export list text and the interface-region even though 6.2.2.2 explicitly states there is no connection.)
What about the following case? It's also ok, isn't it? (Exporting b = 1.)
module m; export m = (a => b); const a = 1; b = 2; end; end.
Yes, it is ok. Note however that constituent-identifier "b" is not a principal identifier for the constant value "1".
P.S. Frank, quite some time ago in the comp.lang.pascal.ansi-iso newsgroup you asked a question about exporting with possibly renaming predefined/required identifiers and I don't think you every got an ISO 10206 based answer.
There was an answer from John Reagan: "I don't think we intended to allow that. I'd have to look closer at your investigation to find the right words." (news:comp.lang.pascal.ansi-iso, subject "Exporting of predefined identifiers", Feb 2003).
I saw John's answer and even with Waldek's later comments, I still think John's thought that exporting of required identifiers wasn't intendend to be allowed is the correct interpretation. However, thoughts and intensions aren't definitive requirements. For an authoritive answer on compliance, the answer has to be derived from the requirments text of ISO 10206 and I haven't seen any good answer which is based on requirements text cites from ISO 10206.
After Waldek's comments (which shot down my first stab at a ISO 10206 based answer), I've spent a considerable amount of time on attempting to develop an ISO 10206 based reasoning as to whether required identifiers are exportable or not. I don't think they are but I still don't have a rock solid, ISO 10206 based reason which definitively rules out exporting the 6.2.2.10 required identifiers.
I will observe that some of the ISO 10206 text is such that it would be difficult to support the case of exporting the 6.2.2.10 required identifiers. For some examples:
1) 6.11.2 informative note 5 states:
"Protected variable-names excepted, a constant-name, type-name, schema-name, variable-name, procedure- name, or function-name that is passed through an interface by a constituent-identifier behaves the same as a constant-name, type-name, schema-name, variable-name, procedure-name, or function-name that does not pass through an interface."
If one presumes the mandatory requirements support this note, then at least the function required identifiers would not be exportable since their constant-expression usage behavior would be different on the import side an the interface from what the usage behavior is on the export side of an interface. The reason being that on the export side the required identifers' defining-point is not contained by the program-block (6.2.2.10) and on the import side the defining point for the imported identifier is contained by the program-block (6.11.3). Thus, 6.3.2 c) would allow usage of required-identifier identified function algorithms on the export side but preclude their usage on the import side since the identifer identifying the function algorithm has a defining-point contained by the program-block.
2) In quite a few of the required identifier requirements (mostly in the required procedures requirements), the requirements are stated in terms which allow for no semantic separation between the syntatic spelling of the identifier used to identify the required-identifier-entity/algorithm and the specified spelling of the required-identifier. Some examples:
a) 6.7.5.4, "In the statement pack(a,i,z) and in the statement unpack(z,a,i) the following shall hold:..."
b) 6.7.5.6, "...the statement bind(f,b) shall ..."
There are no modifiying requirements than I can find which would allow for the usage of any other identier than the required-identifiers of "pack", "unpack", and "bind" in the procedure-name syntax slot in a procedure-statement to active the procedure-block of the corresponding required-identifier procedures.
Since the requirements are explicitly specified as requiring a procedure-statement with an exact spelling of the procedure-identifier to get the specified algorithmic behavior, putting a different identifier in the procedure-identifier slot is nothing more than undefined behavior.
Note: Not all (only some) of the required-identifier entities are specified to require such explicit syntatic forms so the most one can derive from this is that a generalized case of exporting/importing required-identifier entities is most likely not required by ISO 10206.
While the above examples don't definitively rule out all exporting of 6.2.2.10 required-identifiers, they do lend support to John's answer on the question.
[snip]
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Currently GPC doesn't allow exporting `Input' and `Output', but I think it's not too difficult to change this. Do we agree that this is correct (with and without renaming)?
Regardless of the decision on 6.2.2.10 required-identifier exporting, I don't think there is anything to question about ISO 10206 requiring support for exporting/importing (along with renaming) the required-identifier variables "input" and "output". 6.11.4.2 explicitly requires required interface-identifiers StandardInput and StandardOutput with respective constituent-identifiers input and output for the interfaces and those constituet-identifiers denote the required textfiles input and output.
Note: I don't think you just can't arbitarily export input and ouput - other conditions (e.g., usage of input/output in the module parameter list or importing the StandardInput and StandardOutput infaces) also need to be satisfied before input and output are exportable. Those other conditions are needed to get the required text files created in a defined state upon main-program-block activation.
I'll note that 6.11.4.2 takes care in specifying the cases when input and output are implicitly accessable for the read/readln/write/writeln file-variable parameter. I think it is specified in such a manner that one doesn't have to worry about providing implicitly accessable file-variable parameter support for a possibly renamed input or output beig imported through any arbitary, non-required interface. If you don't see the required-identifer spelling of "input", "output", "StandardInput" or "StandardOutput" in the specified syntax slots in the module being compiled, there is no implicitly accessable behavior for read/readln/write/writeln and the file-variable parameter must be used in the code.
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
Note: I haven't fully researched what all the semantic differences are between a principal identifier of value and a non-pricipal identifier. I do note the requirements text takes care to keep the two distinctly separated so I would suppose there is something significant to the difference.
I find this in 6.11.2:
: For each value of the type of an exportÂrange not smaller than the : leastÂvalue of the exportÂrange and not larger than the greatestÂvalue of : the exportÂrange : : a) the exportÂrange shall be within the scope of a definingÂpoint of an : identifier that is a principal identifier of the value; : : b) the occurrence of the exportÂrange shall constitute the definingÂpoint : of that identifier as a constituentÂidentifier for the region that is : the interface denoted by the identifier of the export part that : contains the exportÂrange; and : : c) the constituentÂidentifier so defined shall denote that value and shall : be designated a principal identifier of that value. : : 6 An exportÂrange serves to export only the principal identifiers of the : values within the specified range; it is essentially a shorthand notation : for listing the principal identifiers for each value. The names that are : specified in the exportÂrange serve only to denote the least and greatest : values and are not themselves exported unless they happen to be the : principal identifiers of those values.
So IIUIC, this should work an export `a' and `b' from m2:
module m; export m = (e, a, b); type e = (a, b); end; end.
module m2; export m2 = (a .. b); import m; end; end.
This should also export `a' and `b' from m2 (since `a' is principal, `c' is not):
module m; export m = (e, a, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
And this should fail because m2 has no principal identifier for the value of `c'.
module m; export m = (e, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
Might this be a correct interpretation?
(ISTM they take this effort to facilitate the `..' notation, without introducing implicit exports, or strange situations and ambiguities such as which of possibly several identifiers for a value to export. I don't know if it could have been done any easier, but this question is irrelevant, anyway ...)
What about the following case? It's also ok, isn't it? (Exporting b = 1.)
module m; export m = (a => b); const a = 1; b = 2; end; end.
Yes, it is ok. Note however that constituent-identifier "b" is not a principal identifier for the constant value "1".
AFAICS, only enum values can have principal identifiers, anyway.
- 6.11.2 informative note 5 states:
"Protected variable-names excepted, a constant-name, type-name, schema-name, variable-name, procedure- name, or function-name that is passed through an interface by a constituent-identifier behaves the same as a constant-name, type-name, schema-name, variable-name, procedure-name, or function-name that does not pass through an interface."
If one presumes the mandatory requirements support this note, then at least the function required identifiers would not be exportable since their constant-expression usage behavior would be different on the import side an the interface from what the usage behavior is on the export side of an interface. The reason being that on the export side the required identifers' defining-point is not contained by the program-block (6.2.2.10) and on the import side the defining point for the imported identifier is contained by the program-block (6.11.3). Thus, 6.3.2 c) would allow usage of required-identifier identified function algorithms on the export side but preclude their usage on the import side since the identifer identifying the function algorithm has a defining-point contained by the program-block.
I don't find a 6.3.2 c) (typo?), but so far I tend to agree with your interpretation that:
While the above examples don't definitively rule out all exporting of 6.2.2.10 required-identifiers, they do lend support to John's answer on the question.
[snip]
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Currently GPC doesn't allow exporting `Input' and `Output', but I think it's not too difficult to change this. Do we agree that this is correct (with and without renaming)?
Regardless of the decision on 6.2.2.10 required-identifier exporting, I don't think there is anything to question about ISO 10206 requiring support for exporting/importing (along with renaming) the required-identifier variables "input" and "output". 6.11.4.2 explicitly requires required interface-identifiers StandardInput and StandardOutput with respective constituent-identifiers input and output for the interfaces and those constituet-identifiers denote the required textfiles input and output.
Note: I don't think you just can't arbitarily export input and ouput - other conditions (e.g., usage of input/output in the module parameter list or importing the StandardInput and StandardOutput infaces) also need to be satisfied before input and output are exportable. Those other conditions are needed to get the required text files created in a defined state upon main-program-block activation.
So in concrete examples this means that this should work:
module m; export m = (Output); import StandardOutput; end; end.
And this shouldn't:
module m; export m = (Output); end; end.
(I agree.)
I'll note that 6.11.4.2 takes care in specifying the cases when input and output are implicitly accessable for the read/readln/write/writeln file-variable parameter. I think it is specified in such a manner that one doesn't have to worry about providing implicitly accessable file-variable parameter support for a possibly renamed input or output beig imported through any arbitary, non-required interface. If you don't see the required-identifer spelling of "input", "output", "StandardInput" or "StandardOutput" in the specified syntax slots in the module being compiled, there is no implicitly accessable behavior for read/readln/write/writeln and the file-variable parameter must be used in the code.
Concretely, this should not work (with or without the `=> Foo', right?
module m; export m = (Output {=> Foo}); import StandardOutput; end; end.
program p; import m; begin WriteLn end.
Frank
Frank Heckenbach wrote:
Gale Paeper wrote:
Note: I haven't fully researched what all the semantic differences are between a principal identifier of value and a non-pricipal identifier. I do note the requirements text takes care to keep the two distinctly separated so I would suppose there is something significant to the difference.
I find this in 6.11.2:
[snip]
So IIUIC, this should work an export `a' and `b' from m2:
module m; export m = (e, a, b); type e = (a, b); end; end.
module m2; export m2 = (a .. b); import m; end; end.
This should also export `a' and `b' from m2 (since `a' is principal, `c' is not):
Frank, this comment doesn't seem to match up with the following example as you have typed it. Is there a typo in "export m2 = (c .. b);"?
If you meant it to be "export m2 = (a .. b);" (note the use of "a" instead of the "c" as you have posted), then your comment makes sense and is correct ( or is at least correct as I understand the requirements in this area).
If you meant exactly what you posted "export m2 = (c .. b);", then your comment makes no sense and is not correct in several ways since "export m2 = (c .. b);" does not lead to a constituent-identifier "a" being exported through interface "m2" and the export-range usage is illegal since the imported constituent-identifier "c" from interface "m" is not a principal identifier of the denoted value.
module m; export m = (e, a, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
And this should fail because m2 has no principal identifier for the value of `c'.
module m; export m = (e, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
Might this be a correct interpretation?
Your first and third examples look to me to be the correct interpretation of what should and shouldn't work. I don't know what to make of your second example - either there is a typo in it or you have an incorrect understanding of something.
[snip]
What about the following case? It's also ok, isn't it? (Exporting b = 1.)
module m; export m = (a => b); const a = 1; b = 2; end; end.
Yes, it is ok. Note however that constituent-identifier "b" is not a principal identifier for the constant value "1".
AFAICS, only enum values can have principal identifiers, anyway.
Now that you've pointed it out, I think you're correct that principal identifiers apply only to the constant identifier elements of enumerated types. So, I retract the note part of my comment.
- 6.11.2 informative note 5 states:
"Protected variable-names excepted, a constant-name, type-name, schema-name, variable-name, procedure- name, or function-name that is passed through an interface by a constituent-identifier behaves the same as a constant-name, type-name, schema-name, variable-name, procedure-name, or function-name that does not pass through an interface."
If one presumes the mandatory requirements support this note, then at least the function required identifiers would not be exportable since their constant-expression usage behavior would be different on the import side an the interface from what the usage behavior is on the export side of an interface. The reason being that on the export side the required identifers' defining-point is not contained by the program-block (6.2.2.10) and on the import side the defining point for the imported identifier is contained by the program-block (6.11.3). Thus, 6.3.2 c) would allow usage of required-identifier identified function algorithms on the export side but preclude their usage on the import side since the identifer identifying the function algorithm has a defining-point contained by the program-block.
I don't find a 6.3.2 c) (typo?), ...
It is a typo. It should be 6.8.2 c) which specifies the requirements for function-identifier usage in constant-expressions: ... "An expression shall be designated nonvarying if it does not contain the following" ... "c) an applied occurrence of an identifier as a function-identifier that has a defining-point contained by the program-block or that denotes one of the required functions eof or eoln."
...but so far I tend to agree with your interpretation that:
While the above examples don't definitively rule out all exporting of 6.2.2.10 required-identifiers, they do lend support to John's answer on the question.
The more I try to find a logically consistent reading of the whole text of ISO 10206 in this area, the more I tend to think something was inadvertantly overlooked or missed in specifying the ISO 10206 added mandatory requirements on exportable-name semantics. The missing something would have the effect of something like: "The defining-point of an exportable-name contained by an interface-specification-part shall be contained by the activation of the module-heading containing the interface-specification-part." With something like that, you can get a logically consistent reading of the whole text, still get "normal"/expected usage of the required-identifiers, and avoid the textual inconsistencies and headaches which arise with a 6.2.2.10 required-identifier exporting factor added in the mix.
As the whole text of ISO 10206 is presently written, there seems to be a logic conflict no matter which position you try to take on exporting of 6.2.2.10 required-identifiers. Perhaps I'm missing come critical point, but it seems like if you try to come up with an interpretation of the requirements as written which rules out 6.2.2.10 required-identifier exporting some other requirement doesn't work as it should work and conversely if you try to rule in 6.2.2.10 required-identifier exporting you get logic conflicts with some of the requirements text and informative notes text.
Note: ISO 10206 has the additional semantic requirement on constants, types, variables, etc. "Within an activation of the block, the module-heading, or the module-block, all applied occurrences of that identifier shall denote ..." which isn't in ISO 7185. It has an explicit semantic and syntatic tie to user defined exportable-names and no explicit tie to 6.2.2.10 required-identifiers. But, that requirement just isn't enough by itself to rule out 6.2.2.10 required-identifier exporting and still allow for "normal" usage of those identifiers in other contexts. (The logic chain either rules out using 6.2.2.10 required-identifiers in all contexts or it rules in using 6.2.2.10 required-identifiers in all contexts including export lists. You need some other requirement (or set of requirements) which can be used with that requirement to modify the logic chain in such a manner as to rule out exporting but still allow "normal" usage.)
[snip]
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Currently GPC doesn't allow exporting `Input' and `Output', but I think it's not too difficult to change this. Do we agree that this is correct (with and without renaming)?
Regardless of the decision on 6.2.2.10 required-identifier exporting, I don't think there is anything to question about ISO 10206 requiring support for exporting/importing (along with renaming) the required-identifier variables "input" and "output". 6.11.4.2 explicitly requires required interface-identifiers StandardInput and StandardOutput with respective constituent-identifiers input and output for the interfaces and those constituet-identifiers denote the required textfiles input and output.
Note: I don't think you just can't arbitarily export input and ouput - other conditions (e.g., usage of input/output in the module parameter list or importing the StandardInput and StandardOutput infaces) also need to be satisfied before input and output are exportable. Those other conditions are needed to get the required text files created in a defined state upon main-program-block activation.
So in concrete examples this means that this should work:
module m; export m = (Output); import StandardOutput; end; end.
And this shouldn't:
module m; export m = (Output); end; end.
(I agree.)
I'm in agreement with your should and shouldn't work examples.
I'll note that 6.11.4.2 takes care in specifying the cases when input and output are implicitly accessable for the read/readln/write/writeln file-variable parameter. I think it is specified in such a manner that one doesn't have to worry about providing implicitly accessable file-variable parameter support for a possibly renamed input or output beig imported through any arbitary, non-required interface. If you don't see the required-identifer spelling of "input", "output", "StandardInput" or "StandardOutput" in the specified syntax slots in the module being compiled, there is no implicitly accessable behavior for read/readln/write/writeln and the file-variable parameter must be used in the code.
Concretely, this should not work (with or without the `=> Foo', right?
module m; export m = (Output {=> Foo}); import StandardOutput; end; end.
program p; import m; begin WriteLn end.
Correct, it shouldn't work. Since Program p has neither a program-parameter-list containing an explicit identifier spelling of "output" or an import-part containing the required interface-identifier "StandardOutput", program p has a misssing file-variable parameter error in the procedure-statement "WriteLn". (You need to satisfy one of those conditions to get output implicitly accessable per 6.11.4.2 and therefore meet the 6.10.4 implicitly accessable requirement for omitting the file-variable parameter.)
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
This should also export `a' and `b' from m2 (since `a' is principal, `c' is not):
Frank, this comment doesn't seem to match up with the following example as you have typed it. Is there a typo in "export m2 = (c .. b);"?
If you meant it to be "export m2 = (a .. b);" (note the use of "a" instead of the "c" as you have posted), then your comment makes sense and is correct ( or is at least correct as I understand the requirements in this area).
If you meant exactly what you posted "export m2 = (c .. b);", then your comment makes no sense and is not correct in several ways since "export m2 = (c .. b);" does not lead to a constituent-identifier "a" being exported through interface "m2" and the export-range usage is illegal since the imported constituent-identifier "c" from interface "m" is not a principal identifier of the denoted value.
module m; export m = (e, a, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
I really mean it. Note this part of 6.11.2 (emphasis by me):
: For each value(!) of the type of an exportÂrange not smaller than : the leastÂvalue of the exportÂrange and not larger than the : greatestÂvalue of the exportÂrange : : a) the exportÂrange shall be within the scope of a definingÂpoint : of an(!) identifier that is a principal identifier of the : value;
Here we have an export range whose least-value is the value that `c' has in m2 (which is the value whose principal identifier is `a', because `a' was exported and renamed to `c' from m; we could have gotten the same effect with `const c = a;', for example), and the greatest-value is the value of `b', of course.
So for each value in this range (which are just these two values), we need to have a principal identifier in the scope of m2. These principal identifiers are `a' and `b' since they were exported as principal identifiers from m (whereas `c' was not exported as a principal identifier).
So if I read the standard correctly, the range export indeed does not export the identifier `c', although it's explicitly named, but exports `a' and `b' as principal identifiers (export ranges always export principal identifiers, according to c). See also note 6.
As the whole text of ISO 10206 is presently written, there seems to be a logic conflict no matter which position you try to take on exporting of 6.2.2.10 required-identifiers. Perhaps I'm missing come critical point, [...]
I don't know. Perhaps we should take it to the newsgroup again, but if the standard really is unclear, I'll surely prefer the simpler (and intended, according to John Reagan) option of not allowing it.
Frank
Frank Heckenbach wrote:
Gale Paeper wrote:
This should also export `a' and `b' from m2 (since `a' is principal, `c' is not):
Frank, this comment doesn't seem to match up with the following example as you have typed it. Is there a typo in "export m2 = (c .. b);"?
[snip]
If you meant exactly what you posted "export m2 = (c .. b);", then your comment makes no sense and is not correct in several ways since "export m2 = (c .. b);" does not lead to a constituent-identifier "a" being exported through interface "m2" and the export-range usage is illegal since the imported constituent-identifier "c" from interface "m" is not a principal identifier of the denoted value.
module m; export m = (e, a, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
I really mean it. Note this part of 6.11.2 (emphasis by me):
[snip]
So if I read the standard correctly, the range export indeed does not export the identifier `c', although it's explicitly named, but exports `a' and `b' as principal identifiers (export ranges always export principal identifiers, according to c). See also note 6.
Geesh! With note 6 and a more careful reading of the requirements, I see you are indeed correct that the requirements require the behavior you've described for the example.
That aspect of the export-range feature doesn't seem to be very Pascal-like to me. However, regardless of one's opinion about it, it is required by the export-range requirements and thus must be supported to be fully compliant with ISO 10206.
As the whole text of ISO 10206 is presently written, there seems to be a logic conflict no matter which position you try to take on exporting of 6.2.2.10 required-identifiers. Perhaps I'm missing come critical point, [...]
I don't know. Perhaps we should take it to the newsgroup again, but if the standard really is unclear, I'll surely prefer the simpler (and intended, according to John Reagan) option of not allowing it.
I think a revisit/follow-up in the newsgroup or directly with John Reagan is probably warrented. First, until one can show an explicit, concrete derivation from ISO 10206 requirments which proves GPC's implementation is compliant, there will always be an open question as to whether or not GPC is compliant in this area. Second, if it does turn out that there is indeed a problem with ISO 10206 as it is presently written, John Reagan, as the X3J9 Secretary, needs to be aware of it so the deficiency can be addressed if and when X3J9 undertakes a maintenance revision of ISO 10206.
In case there is any doubt, I also prefer the simpler option of not allowing it. (Allowing it would add a great deal of complexity both from language implementors and language users perspectives. There is no real world problem that I'm aware of that would justify that sort of added complexity.)
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
As the whole text of ISO 10206 is presently written, there seems to be a logic conflict no matter which position you try to take on exporting of 6.2.2.10 required-identifiers. Perhaps I'm missing come critical point, [...]
I don't know. Perhaps we should take it to the newsgroup again, but if the standard really is unclear, I'll surely prefer the simpler (and intended, according to John Reagan) option of not allowing it.
I think a revisit/follow-up in the newsgroup or directly with John Reagan is probably warrented. First, until one can show an explicit, concrete derivation from ISO 10206 requirments which proves GPC's implementation is compliant, there will always be an open question as to whether or not GPC is compliant in this area. Second, if it does turn out that there is indeed a problem with ISO 10206 as it is presently written, John Reagan, as the X3J9 Secretary, needs to be aware of it so the deficiency can be addressed if and when X3J9 undertakes a maintenance revision of ISO 10206.
I agree. Are you going to write to the newsgroup or to John (since you did most of the analysis)?
In case there is any doubt, I also prefer the simpler option of not allowing it. (Allowing it would add a great deal of complexity both from language implementors and language users perspectives. There is no real world problem that I'm aware of that would justify that sort of added complexity.)
Also agreed. For now, I won't allow it. If it will ever be stated that it is required, I'll have to consider the issue again. (But since John indicated it wasn't intended, I don't expect this.)
Frank
Second try. For some reason the first never made it to the GPC mailing list server.
Frank Heckenbach wrote:
Gale Paeper wrote:
Note: I haven't fully researched what all the semantic differences are between a principal identifier of value and a non-pricipal identifier. I do note the requirements text takes care to keep the two distinctly separated so I would suppose there is something significant to the difference.
I find this in 6.11.2:
[snip]
So IIUIC, this should work an export `a' and `b' from m2:
module m; export m = (e, a, b); type e = (a, b); end; end.
module m2; export m2 = (a .. b); import m; end; end.
This should also export `a' and `b' from m2 (since `a' is principal, `c' is not):
Frank, this comment doesn't seem to match up with the following example as you have typed it. Is there a typo in "export m2 = (c .. b);"?
If you meant it to be "export m2 = (a .. b);" (note the use of "a" instead of the "c" as you have posted), then your comment makes sense and is correct ( or is at least correct as I understand the requirements in this area).
If you meant exactly what you posted "export m2 = (c .. b);", then your comment makes no sense and is not correct in several ways since "export m2 = (c .. b);" does not lead to a constituent-identifier "a" being exported through interface "m2" and the export-range usage is illegal since the imported constituent-identifier "c" from interface "m" is not a principal identifier of the denoted value.
module m; export m = (e, a, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
And this should fail because m2 has no principal identifier for the value of `c'.
module m; export m = (e, b, a => c); type e = (a, b); end; end.
module m2; export m2 = (c .. b); import m; end; end.
Might this be a correct interpretation?
Your first and third examples look to me to be the correct interpretation of what should and shouldn't work. I don't know what to make of your second example - either there is a typo in it or you have an incorrect understanding of something.
[snip]
What about the following case? It's also ok, isn't it? (Exporting b = 1.)
module m; export m = (a => b); const a = 1; b = 2; end; end.
Yes, it is ok. Note however that constituent-identifier "b" is not a principal identifier for the constant value "1".
AFAICS, only enum values can have principal identifiers, anyway.
Now that you've pointed it out, I think you're correct that principal identifiers apply only to the constant identifier elements of enumerated types. So, I retract the note part of my comment.
- 6.11.2 informative note 5 states:
"Protected variable-names excepted, a constant-name, type-name, schema-name, variable-name, procedure- name, or function-name that is passed through an interface by a constituent-identifier behaves the same as a constant-name, type-name, schema-name, variable-name, procedure-name, or function-name that does not pass through an interface."
If one presumes the mandatory requirements support this note, then at least the function required identifiers would not be exportable since their constant-expression usage behavior would be different on the import side an the interface from what the usage behavior is on the export side of an interface. The reason being that on the export side the required identifers' defining-point is not contained by the program-block (6.2.2.10) and on the import side the defining point for the imported identifier is contained by the program-block (6.11.3). Thus, 6.3.2 c) would allow usage of required-identifier identified function algorithms on the export side but preclude their usage on the import side since the identifer identifying the function algorithm has a defining-point contained by the program-block.
I don't find a 6.3.2 c) (typo?), ...
It is a typo. It should be 6.8.2 c) which specifies the requirements for function-identifier usage in constant-expressions: ... "An expression shall be designated nonvarying if it does not contain the following" ... "c) an applied occurrence of an identifier as a function-identifier that has a defining-point contained by the program-block or that denotes one of the required functions eof or eoln."
...but so far I tend to agree with your interpretation that:
While the above examples don't definitively rule out all exporting of 6.2.2.10 required-identifiers, they do lend support to John's answer on the question.
The more I try to find a logically consistent reading of the whole text of ISO 10206 in this area, the more I tend to think something was inadvertantly overlooked or missed in specifying the ISO 10206 added mandatory requirements on exportable-name semantics. The missing something would have the effect of something like: "The defining-point of an exportable-name contained by an interface-specification-part shall be contained by the activation of the module-heading containing the interface-specification-part." With something like that, you can get a logically consistent reading of the whole text, still get "normal"/expected usage of the required-identifiers, and avoid the textual inconsistencies and headaches which arise with a 6.2.2.10 required-identifier exporting factor added in the mix.
As the whole text of ISO 10206 is presently written, there seems to be a logic conflict no matter which position you try to take on exporting of 6.2.2.10 required-identifiers. Perhaps I'm missing come critical point, but it seems like if you try to come up with an interpretation of the requirements as written which rules out 6.2.2.10 required-identifier exporting some other requirement doesn't work as it should work and conversely if you try to rule in 6.2.2.10 required-identifier exporting you get logic conflicts with some of the requirements text and informative notes text.
Note: ISO 10206 has the additional semantic requirement on constants, types, variables, etc. "Within an activation of the block, the module-heading, or the module-block, all applied occurrences of that identifier shall denote ..." which isn't in ISO 7185. It has an explicit semantic and syntatic tie to user defined exportable-names and no explicit tie to 6.2.2.10 required-identifiers. But, that requirement just isn't enough by itself to rule out 6.2.2.10 required-identifier exporting and still allow for "normal" usage of those identifiers in other contexts. (The logic chain either rules out using 6.2.2.10 required-identifiers in all contexts or it rules in using 6.2.2.10 required-identifiers in all contexts including export lists. You need some other requirement (or set of requirements) which can be used with that requirement to modify the logic chain in such a manner as to rule out exporting but still allow "normal" usage.)
[snip]
The two exceptions are input and output. For those two, defining points are created in the module-heading region either with the useage as a module parameter or with importing the required interfaces StandardInput and StandardOutput into the module-heading. (StandardInput and StandardOutput are the other two of the four required identifiers not covered by 6.2.2.10 but interface identifiers aren't exportable-names and thus cannot be renamed.)
Currently GPC doesn't allow exporting `Input' and `Output', but I think it's not too difficult to change this. Do we agree that this is correct (with and without renaming)?
Regardless of the decision on 6.2.2.10 required-identifier exporting, I don't think there is anything to question about ISO 10206 requiring support for exporting/importing (along with renaming) the required-identifier variables "input" and "output". 6.11.4.2 explicitly requires required interface-identifiers StandardInput and StandardOutput with respective constituent-identifiers input and output for the interfaces and those constituet-identifiers denote the required textfiles input and output.
Note: I don't think you just can't arbitarily export input and ouput - other conditions (e.g., usage of input/output in the module parameter list or importing the StandardInput and StandardOutput infaces) also need to be satisfied before input and output are exportable. Those other conditions are needed to get the required text files created in a defined state upon main-program-block activation.
So in concrete examples this means that this should work:
module m; export m = (Output); import StandardOutput; end; end.
And this shouldn't:
module m; export m = (Output); end; end.
(I agree.)
I'm in agreement with your should and shouldn't work examples.
I'll note that 6.11.4.2 takes care in specifying the cases when input and output are implicitly accessable for the read/readln/write/writeln file-variable parameter. I think it is specified in such a manner that one doesn't have to worry about providing implicitly accessable file-variable parameter support for a possibly renamed input or output beig imported through any arbitary, non-required interface. If you don't see the required-identifer spelling of "input", "output", "StandardInput" or "StandardOutput" in the specified syntax slots in the module being compiled, there is no implicitly accessable behavior for read/readln/write/writeln and the file-variable parameter must be used in the code.
Concretely, this should not work (with or without the `=> Foo', right?
module m; export m = (Output {=> Foo}); import StandardOutput; end; end.
program p; import m; begin WriteLn end.
Correct, it shouldn't work. Since Program p has neither a program-parameter-list containing an explicit identifier spelling of "output" or an import-part containing the required interface-identifier "StandardOutput", program p has a misssing file-variable parameter error in the procedure-statement "WriteLn". (You need to satisfy one of those conditions to get output implicitly accessable per 6.11.4.2 and therefore meet the 6.10.4 implicitly accessable requirement for omitting the file-variable parameter.)
Gale Paeper gpaeper@empirenet.com