J3/97-235 Date: 12 Sep 1997 To: J3 From: R. Maine Subject: 97-007R1 The following are the edits incorporated in 97-007R1. First, a new editorial construct added. I've made a new kind of shaded note that I've tagged J3Note. They look like the other notes except that they are not numbered and they have a header that says "J3 internal note". The intent is to use these to note places where things still need to be resolved; they will all be removed in the actual standard. The separate tag makes it easy to automatically find them so that they don't end up left in by accident. We might possibly even end up doing something like leaving some such internal notes in the final Frame document, but making them invisible (and non-space consuming) so that they aren't in the formal standard (not even as informative text). We can worry later about whether we want something like that. In the meantime, this seems like a better way to note such unresolved issues than just in a paper, which might get forgotten about in a year or two. 97-193r1, named scratch files. "is prohibited" -> "is not permitted" in the [140:13+] edit to match the wording in the preceding sentence. 97-202R1, subobject cleanup. A few trivial changes on the order of changing "a" to "an" and adding a "then" after an "if" clause. One dash added in the r1 was incorrect; the r0 version without the dash was used instead. 97-204R1, intent for pointer dummy args A few trivial grammatical and spelling corrections. Changed 2 xrefs of the deleted section 12.5.2.1 to point to 5.1.2.3. 97-206 Per the vote at meeting 142, did the edits to case (ii) of the MINVAL and MAXVAL results as suggested in this paper. 97-208R1 Two punctuation changes. Otherwise electronically imported, so it really should be identical. 97-216R2, async i/o (partial edits) Substantial rewording throughout. Much more than I normally anticipate doing (or so I hope - this is a lot of work). People probably ought to really check out this one. I pretty much completely rewrote a lot of it. (Yes, if people dislike what I did, we can take it all out, but I think the original is going to need quite a bit of work, whether y'all like the way I did the work or not). Some explanatory notes about why I did some things below, but see the document for details and exact words. There are also quite a few open questions on this paper. Instead of further holding up the 97-007R1 until all those could get resolved, I've just left temporary notes about work that is needed in a few places. This will obviously need (at least) one more pass. To find the edits for this item, look for the change bars in R214, R426, R503, R905 (but I didn't redo anything in those 4 places), 5.1.2.12, 5.2.10 (new numbering, not the old), 9.3.4.11, 9.3.5, 9.4.1, 9.4.1.9, 9.4.1.10, 9.4.1.11, 9.4.4, 9.5 (new numbering), 9.6, 9.7.1, 9.7.1.14, 9.7.1.23, 9.7.1.24, 11.3.2, 12.3.1.1, 14.7.5, 14.7.6, C.6.3. Added a few index entries (but probably not enough - just a few that happened to occur to me at the time). Several changes to refer to semantics instead of syntax where practical. Like saying "asynchronous i/o statement" instead of "i/o statement with an ASYNCHRONOUS= specifier with a value YES". Simillarly, instead of talking about "the value returned by the ID= specifier of a READ or WRITE statement" we instead talk about the identifier of a data transfer operation and we define that concept in 9.4.11. The wording about WAIT, CLOSE, INQUIRE, and file positioning statements being "considered to be data transfer statements for purposes of end of file, end of record, and error processing" opens up several confusions and I don't think it is either necessary or useful. (Could it, for example be the "corresponding data transfer statement" for itself? Obviously not, but its better if we use wording that doesn't invite such silly questions). We already refer to the appropriate sections for descriptions of the ERR=, END=, EOR=, and IOSTAT= specifiers. We just need to say (like we do) that these statements may perform wait operations and then also say that wait operations may trigger the error actions in whatever statement executes them. This ends up needing only one sentence in the close and file positioning statements to say that they perform the wait operations. We then define in one place (the new 9.5.2) what it means to perform a wait operation. Several changes for style, consistency, spelling, etc. One I noticed several places. A "statement" and an "operation" are different breeds of animal. We can talk about a WAIT statement doing/executing/performing/whatever a wait operation, but we shouldn't say that a WAIT statement "is" a wait operation; simillar principles elsewhere. Combined and moderately reworded two of the notes in 5.1.2.12. The statement (and note) about the ASYNC attribute being allowed for any variable had some wording problems. (You can't specify it for "any" variable, only for named variables and structure components - recall that array elements, for example, are variables). The statement seems redundant anyway, so I just omitted it instead of comming up with a rewording. Added mention and an xref in 5.1.2.12 about implicitly getting async attribute. And deleted the note from 5.1.2.12 about what it means to be pending. This isn't the place to treat that; we can xref into section 9 if desired (but I didn't because the best place to xref might well move to a different section in the next revision). The discussion of how asynchronous I/O works seems out of place in 9.3.4.11 under the OPEN statement. This material goes better under data transfer statements, with possibly an overview in Annex C. While adding ASYNCHRONOUS to R912 (io-control-spec), I noticed some largely unrelated problems with the first 2 sentences of 9.4.1. The first sentence has a numbered list that seems to be of little use. It doesn't say anything that isn't said more clearly and explicitly in the rest of the section. If it were going to stay, we'd need to add something about the async specifier to it. The sense of the sentence is also backwards (it should say that a control information list is an io-control-spec-list instead of the other way around) and uses "that" in a context that clearly calls for "which." I eliminated the numbered list and rewrote these 2 sentences. I'm somewhat dubious of the need to define the term "control information list" at all; it is used only in this section and is nothing but a synonym for io-control-spec-list. But I suppose we need something for a section title, so I left it alone. In the constraints for R912, require ASYNC to have the value YES when ID= appears, instead of just requiring ASYNC to appear. Note that this is appropriate for a constraint because the value of ASYNC is known at compile time (unlike the simillar case with ADVANCE and SIZE/EOR, where the restriction to have the value YES is separately stated in the text). Added words to make async case insensitive (just added it to simillar words about advance.) I didn't think it worth a note in 9.4.1.9 (size=) about the various things that can be a wait operation was really needed here - its sort of a minor side light. Better to just state that well in the areas that are more specifically about async i/o. Paper 97-216r2 had a few notes sandwiched between sections marked as "no longer part of the edits." I ignored those notes (for now) because they didn't make sense out of context, and the context isn't (yet) there. The para about when errors can be flagged doesn't seem to have much to do with the 9.4.4.4 "Data transfer" subsection. I moved it to 9.4.4. Indeed, now that I consider it, the para about when the data transfer can occur also fits better in 9.4.4 because that section has the outline of what order things happen in. (Though said outline needs work, as discussed in the technical questions below). The terminology used to describe "corresponding" data transfer and wait statements/operations is a bit inconsistent, giving rise to several questions. For example, a WAIT statement without an ID= specifier "waits for all pending...", but it isn't explicit whether this means it then constitutes the "corresponding" wait operation; for example, could we do read(unit,asynchronous='yes')... read(unit,asynchronous='yes',id=id)... wait(unit) wait(unit,id=id) The answer depends on whether the first wait was the "corresponding" one for the second read or whether it just waited for it without being "corresponding". I'm assuming that it was also the "corresponding" one. I'll try to straighten this wording out, perhaps by mostly avoiding the "corresponding" terminology.... (later) Yes, I now say that the pending data transfer operation has an identifier and use that concept to avoid all the stuff about corresponding statements. The "one or more" terminology in the description of the WAIT statement appears incorrect. I see no restriction that says you couldn't do a WAIT statement with no ID= specifier when there were in fact no pending data transfers on the unit. We need to say (and I presume this is what we want) that a pending data transfer is initiated only by a *successful* data transfer statement. If an error is detected during the data transfer statement, then it does not leave a data transfer operation pending, it does not define a pending i/o storage sequence, and any variable in its ID= specifier becomes undefined. For example, I'm assuming that the following is illegal if an error occurs. write(unit,asynchronous="yes",id=my_id,iostat=iostat) ... if (iostat/=0) write (*,*) "Ignoring error." !-- If there was an error, my_id is undefined, so the following is bad. wait(unit,id=my_id) Edited note 9.23 (old numbering) to say "for sequential input" instead of "during execution of a sequential input statement". Likewise for the nonadvancing stuff in the same sentence. Because end-of-file may now occur other than during the execution of the data transfer statement. Was there any particular reason for the constraint that ID= and PENDING= can't be used with the FILE= form of INQUIRE. I agree that it seems more natural to use them with UNIT=, but there are no comparable constraints on other INQUIRE specifiers that make sense only for connected files (such as NEXTREC). Presumably the processor is supposed to be able to figure out the unit number from the file name (hmm, in fact the NUMBER= specifier makes that pretty explicit). Having the constraint for these 2 specifiers only seems inconsistent. I omitted it. If I've missed something, let me know - its trivial to add back in. Added a restriction for ID= in INQUIRE just like that for WAIT; it has to be the identifier of a pending data transfer. As for WAIT, the processor doesn't have to check this. Also, I assume the wording was just confused when it says that if PENDING= returns false, then *ANY* pending data transfer operations on the unit are completed. That only makes sense to me in the case without ID=. I presume that when ID= is present, only that particular data transfer is considered completed. Whereas I agree that it is better to say 'the value "YES"' (with quotes around "YES" instead of 'the value YES', all the existing text omits the quotes, so I also omitted them in the new text for the ASYNC specifier in INQUIRE. (Its far too much work for too little benefit to find and change all the existing simillar occurances). Added words in 11.3.2 to allow ASYNCHRONOUS to be respecified for local names of variables accessed via USE. The proposal seems to assume that things like this are allowed, but unless I added an exception to the general prohibition against respecification, 11.3.2 would have been pretty explicit about forbidding it. This needs better treatment than this one obscure phrase, though; see my open questions. I added the rationale and conceptual model to Annex C, with some editing, mostly to get rid of the first person and some other trivia. I didn't spend much time editing this for style consistency, figuring that such things aren't as big a deal in the rationale (besides which I'm running low on time). While on the subject I moved C.6.1.5 up a heading level to C.6.2 where it fits better. Upper and lower case. Noticed a major omission from the edits for requiring both upper and lower case. I found and fixed 15 places where there were statements like "If a processor is capable of representing letters in both upper and lower case, " and made the obvious changes. 7 in c9, 6 in c10, 1 in c13, and 1 in Annex b. Mostly just removed the conditional clause. In the C13 case (in ACHAR), the whole requirement became moot, and I removed it. Misc edits Table 7.6. "Disjunction" uncapitalized per email comment. Note 7.41. Deleted second "For example" and combined paras per email comment that 2 "For example"s in one example was confusing. Changed ".1" to ".0" on last line of table in 10.5.4.1.2 per proposed answer to f95 interp request in 97-225. Last line of C.4.6. "N+1" -> "N" per email note. F95 "typo". While checking to see whether nonzero should be hyphenated, I noticed that the document has zillions of places where it is not hyphenated and 2 places where it is. I changed the 2. Some open questions on async i/o. These still need work. Do we really want to allow async as a component attribute spec? I sent out an email on this question, but haven't heard a single comment in reply. Added a J3Note in 4.4.1. In 5.1.2.12, the requirements for the async attribute seem a little broad. Item 2 says "while an [i.e. *ANY*] asynchronous data transfer operation is pending." Can't we safely narrow this requirement to only apply while the particular data transfer operations are pending? We could still allow other pending data transfers that this variable has nothing to do with. I've done nothing on this. Exactly what variables get the async attribute implicitly? The text is not clear on the point and I was unable to fix it up because I was unsure of the intent. recall that subobjects of variables are also variables. Example: read(...,asyncronous='yes') a(7), b%c%d, e(i) Is just a(7) implicitly async, or all of "a"? Simillarly, just b%c%d or all of b? How about if b%c is a pointer? Is "i" implicitly async (it does "appear in the i/i list). I need guidance on the technical intent here before I can craft words. I put the words pretty much from 97-216r2 in, but they aren't really adequate to specify the exact meaning. Also, does the implicitly conferred async attribute apply only to the current scoping unit or possibly also to the host (if this is in an internal or module procedure) and/or "child" (internal procedure) scoping units. Added a J3Note in 9.4.1.10. While on the subject of the async attribute, its scoping and inheritance rules are never explicitly stated....and the intent isn't clear to me in all cases. It is clearly intended that a variable can have the async attribute in some scoping units, but not in others. But the details of how this works are never specified. If a module variable is specified as async in the module, does the attribute also apply in scoping units using the module? How about host association - is a variable that is async in the host also async in the internal or module procedures contained in the host? And does an async statement in a contained scope "hide" any variable of that name from the host or just apply the async attribute to the variable from the host? These questions all need to be answered. (Makes me wonder whether we wouldn't be better off just making async follow the same rules as the other attributes in that a variable either has it or not and it doesn't change from one scoping unit to another - I suppose we already decided not to do it that way). Added a J3Note in 5.2.10. Section 9.4.4 "Execution of a data transfer I/O stmt" needs work. I don't think that the 2 small edits proposed look particularly close. For example, they leave the requirement that file positioning has to occur during execution of the data transfer statement, which isn't what we want to say. I think what we probably need here is a separate outline of what goes on in an async data transfer, instead of trying to shoehorn it into the outline of the sync case, because there are some things that are pretty different. In fact, I think it best to perhaps phrase it as a description of the whole operation, identifying which parts have to happen during the data transfer statement itself, which parts happen during the wait operation, and which parts can happen anytime in between. The 9.4.4.x subsections can probably stay largely as is (with one exception noted below) and referenced for both the sync and async outlines. I was thinking of taking a wing at this myself, but the people working on the proposal probably have a better idea of the steps; if they don't, I'll try. So I left out the 2 edits to the numbered list in 9.4.4 and instead added a J3Note. And possibly related to the preceeding question, I thought that the current model was that the complete i/o list for async i/o was supposed to be established during the data transfer statement, before actually doing the data transfer. Otherwise, I'm not sure how the pending i/o storage sequence is well defined. I can't find anywhere that says this, though. It probably ought to be one of the steps mentioned in the above elaboration. And paras 2-3 of 9.4.4.4 "Data transfer" directly contradict this, so they may need to be edited to distinguish the sync and async cases. I added a J3 note in 9.4.4.4. Any particular reason why a WAIT statement can't have more than one ID= specifier (or alternatively a vector-valued one). It can wait for multiple pending data transfers (in the case where ID= is omitted), so the basic semantics must be defined (in particular that it waits until all of them are done). I don't see why it couldn't wait for multiple specified ones as well. I didn't do anything about this because there is nothing wrong with it as is; I just wondered about why the restriction. Is a WAIT statement allowed on a unit that was not opened for async i/o? I see no restriction against it. Of course, it would have to be the form with no ID= specifier because there won't be any pending data transfer operations. We probably ought to answer this explicitly instead of waiting for the interp request. I'm not sure which answer we want - either would seem to "work." The Para in 9.4.1.10 that tries to define pending I/O storage sequence affector variables needs more work than I have time for right now. Paper 97-216R2 put off most of the other material about such affectors til later; this can go with that material. In 14.7.6(16), it violates causality to say that you need to know the results of the data transfer to determine which variables in a namelist group became undefined when the initiating READ statement was executed. I deleted that exception and left it saying that they all become undefined. I'm picturing that the "unchanged" ones later get redefined back to their original values, but that's hard to say. But we certainly(?!) can't make the definition status non-causal. My "cop-out" in the description of the wait operation was "If the data transfer operation is an input operation that completed without error, the storage units of the I/O storage sequence then become defined with the values as described in 9.4.1.9 and 9.4.4.4." but I'm not claiming that to be a particularly good wording. In C.6.3 the consecutive sentences The addresses of the list items must be computed before the asynchronous READ/WRITE statement completes. There is still an ordering requirement on list item processing, to handle things like READ (...) N,(a(i),i=1,N). sound contradictory to me since the value of N changes the addresses of the list items - and potentially in more complicated ways than just the size of a contiguous chunk. This leaves me uncertain of what the actual spec is. I added a J3 note as a reminder to address this. I didn't yet add the words to the normative text to go with the explanation in the model C.6.3 that errors can be reported on any subsequent i/o statement for the same unit if there was no ID=. I think the best way to cover all the bases for this case is to say that any such statements may perform the wait operation. That would cover us on such details as making the operation and its async i/o storage sequence no longer be pending. Probably not very hard to word, but I've just run out of time to make sure I do it right. (Probably fewer words than this para, but I can be sloppy here). Added a J3Note in C.6.3.