J3/98-144 Date: 4 May 1998 To: J3 From: Richard Maine Subject: Edits incorporated in 98-007R1 This paper describes the changes in J3/98-007R1 relative to the previous f2k draft, J3/98-007. All page/line references are to J3/98-007 unless otherwise noted. I have flagged several items as needing further attention in my opinion. For convenience in future citation, I have numbered these. They are all flagged with ***ACTION ITEM xx. In many of these cases I have also put a J3 note into the document as a reminder. The change bars in 98-007r1 are relative to J3/98-007. misc edits [84:12] removed typo "(" from the middle of "ALLOCATE". [150:25] "governsR" -> "governs" paper 98-121r1, procedure pointers I'm afraid I did a fairly hasty job of editing this one as I'm getting low on time. In particular, I didn't spend much time in cross-checking the edits with other areas of the standard. (Still took me several weeks - having a hard time freeing up time for J3 work). [60:31-33] The stuff about "appears in a type declaration, external stmt or procedure declaration stmt" is incorrect. The name has to appear in specific contexts in those statements, not just anywhere. (We've had to do fixups for this kind of overstatement before). I started to make the sentence more specific about the context, but it becomes too long and awkward. But those specific context details are already covered elsewhere anyway, so I just rewrote this to say that a name may be given the external attribute by these kinds of statements. In the process, went back to having the first sentence in the section say something about what the attribute means, parallel to the other sections in the area. While on the subject, since this looks like a complete list of ways that a name can get the external attribute, I added a sentence about getting the attribute implicitly. It seems to me that otherwise the list is misleading in its incompleteness. But... ***ACTION FLAG*** We badly need an xref for how a name can get the external attribute implicitly. I wasn't sure where the bext xref was and didn't take the time to find one. Left a J3note there instead. ***END ACTION "explicit type" -> "explicitly specified type" Appearance of an external name as a function reference etc just makes the name a function name. It doesn't limit it to external or dummy functions. It could be a pointer. The only point to be made here is the functionness, so there is no reason to list the various kinds of functions that it could be in this sentence. [61:14+] Added some articles to avoid starting sentences with bnf. "must" -> "shall" Moved R519c up right after R519b instead of after the first few constraints. This follows the pattern used in 5.1. besides, the proposed division of the constraints seems rather arbitrary. ***ACTION FLAG You don't want the second constraint (about matching characteristics) to be a constraint because it isn't necessarily checkable at compile-time. Well, the point is perhaps arguable, but I *SERIOUSLY* doubt that you want it to be inconsistent depending solely on the syntax used for declaration (a constraint when you use an abstract interface, but not a constraint when you use an interface body). And the constraint doesn't even make sense for the dummy argument case. So I turned it into text and made the wording simillar to that in 12.3.2.1. Oh, and the third constraint has simillar problems. It can't be a constraint either. Being rushed, I haven't written the revised words for these; just left a J3 note instead. ***END ACTION FLAG Instead of using a constraint to restrict what attributes are allowed, it seems a little more straightforward to just define a that includes these attributes. This is a close call; either way works, so if there is objection, I'll change it back. I'm bothered by the inconsistent bnf terminology in that is not the name of a . Changed to (which is anyway more parallel to 5.1). All places where it was referenced also. On further thought, the term identity bothers me anyway. It brings to mind identity operators. Most of the definitions I see in the dictionary have something to do with sameness; one definition refers to the distinguishing characteristics of an individual, which is somewhat more along the right line but still not as good as just entity. (Makes one almost think that the derivation might be from "id entity" but that isn't what the dictionary shows. It shows derivation from the Latin "idem", meaning "same". Admitedly I'm at work where I don't have a really good dictionary convenient; much better ones are at home). A search of the standard reveals that the term identity is used only 3 times, and in all of those places it refers to the "+" operator. We already have a host of subtly different terms for "thingos" - object, entity, data entity, and I'm sure some other forms. Lets not introduce another. Lets just call this a . It seems consistent with the existing definition of "entity" and I can't see that the extra "id" in front of "entity" adds anything. So changed to here and elsewhere. Section 5.1 talks about attributes being given to entities instead of to their names. I'm not sure which is the best point of view, but lets at least be somewhat consistent here. The constraint against proc-entity-name being the name of an accessible module procedure seems redundant and inconsistent. We already have a general rule against respecifying attributes of anything that is accessible from a module. I don't know why we need to repeat this particular case. Yes, simillar cases are common sources of programmer error. But we don't usually add redundant constraints just for clarification (we do it in notes). Besides, if that were the point then why do it here and not in the places where the errors are being made today - for instance we don't say in 5.1 that an object-name in a type declaration statement shall not be the same as the name of an accessible module procedure (or for that matter of anything else accessible from a module). I omitted this. ***ACTION FLAG There was a floor suggestion that a note explaining the 2nd restriction after R519c (now R523). I haven't taken the time to craft such a note. Added a J3 note instead. There was also a suggestion that the forward reference to section 12 in note 5.19 was undesirable. I haven't done anything about that either. Added a J3 note. *** END ACTION FLAG I abbreviated the table headers instead of making them complete sentences. Nothing really wrong with them except that they were long enough to make the table formatting awkward. Why can an intrinsic procedure name be used for an external procedure or a procedure pointer, but not for a dummy procedure? I assume this was an accidental omission, which I recyfied. I think it would be better to discuss in one place the implications of giving the EXTERNAL attribute to the name of an intrinsic procedure. The current phrasing is too tied up in syntax details. All we want to say under the PROCEDURE statement is that it confers the EXTERNAL attribute. The semantics of what it means to give something the external attribute are then the same, regardless of whether the attribute was conferred by an EXTERNAL statement, an EXTERNAL attribute in a type declaration statement, or a PROCEDURE statement. But the old text already has this problem and I don't have the time to straighten it all out, so I entered the material on this as is. [118:12-13] "procedure pointer that has a result type" -> "function procedure pointer". Just a simpler way to say it. I find the wording "having an interface to a pure procedure" a bit confusing. I changed it to just "that is pure". This parallels the wording used in 12.4.1.2. If the wording isn't good enough here then it probably wasn't good enough there. Likewise for the other simillar phrase. I added "that is not elemental" at the end of this insert. I know it is superfluous (since a procedure pointer can't be elemental), but I think it helps clarify what difference in characteristics we are talking about; otherwise one might read it as saying that an intrinsic elemental procedure could be the target of any procedure pointer object, even one with different argument types. [155:20+ and 23+] Used bnf for and . [204:26-27] In the first constraint, move accessible so it modifies all the classes of procedures mentioned instead of just module procedures. It is confusing to pointedly say that module procedures have to be accessible, while not saying the same thing about the other kinds. This implies a difference that doesn't exist. Alternatively it would probably be ok to just omit the "accessible" completely, as I think its probably already implied, but this way seems safer. I suspect that someone didn't understand the full purpose of the original wording - but since that purpose is now largely moot, that's ok. I believe that the original "accessible as" wording was to cover things like an external procedure that is given an interface in a module. To users of the module, this can then be "accessible as" a module procedure, even though the original was an external procedure. But we no longer care whether or not it is a module procedure, just that its interface is explicit, so this fine point is moot. Hmm. But it is still relevant when the optional "MODULE" keyword appears. I've changed the wording of that constraint back to an "accessible as" form like f90/f95 in order to avoid questions of possible unintended technical incompatability with f90/f95. It would be a slightly subtle interpretation question as to whether the proposed wording change would have the same interpretation as the old words. But I think better to just use the old words and avoid the question. Also, needed to be more specific that the appearance of MODULE only constrains the procedure-names of that particular statement; the proposed wording was ambiguous and could be interpreted as having effect on all procedure statements in the interface block. I see several problems in the last constraint here. Mostly the revised wording is subject to multiple interpretations. For example, the f95 words talk about previous specification in *THE SAME* specification part, wheas the new wording talks about all interface blocks in *ANY* specification part. I can read that "any" in 2 different ways. Simillarly, the proposed new wording restricts against specification more than once "in *A* procedure-stmt", which leaves me unsure about whether you could specify it once in one statement and then again in some other statement. It appears to me that the only change here really relevant to procedure pointers was the change of module-procedure-stmt to procedure-stmt (twice), so I did that. The rest just appears to be rewriting the constraint, possibly on the theory that as long as the constraint had an edit anyway, try to rewrite it more clearly. I won't claim that the original wording was ideal, but it has gone through quite a bit of subtle interpretation processing. It looks to me like the proposed new wording is in some ways more vague than the original and invites us to go through the interpretation process again (possibly coming up with different answers). Unless this actually has some specific relevance to the addition of procedure pointers, I'd prefer to treat any possible rewriting of this constraint as a separate issue. There have been strongly debated interps on the question. If we even want f2k to change the answer to those interps, I don't necessarily object (as long as it is a compatable change, which it probably could be). But if so, I think it merits its own paper instead of slipping in as part of the pdt edits. [207:25+] Added this new section after the new section also added here for derived type i/o in the same batch of edits. So it and its xrefs become 12.3.2.1.4. Put some of the commentary in code samples into lower case. I left the real code part alone, just changing the comments. I'd like to get away from the style of putting every code sample completely in upper case. Yes, I know the old ones were. But I think the consistency in this isn't that important. Ideally, we'd change some of the older samples also, but it isn't a big enough deal to be worth spending time on. Maybe someday when I'm feeling to burned out to do work that requires thinking.... Last sentence in note 12.x plural to better agree with the subject. And can -> may. The instructions on where to add note 12.y were unclear to me. It just said [207:42-45]. I'm not sure whether that means to add the note after that paragraph or to insert the note so that it would be those line numbers (i.e. before the paragraph). I doubt it means to have the note replace the paragraph. I put it before the para, mostly because thats where the other notes were just moved. Also, I reworded the note. Although we may believe the statements to be true, I don't think the standard is usually quite as explicit as to say, even in a note, that some style is "better practice" than another. In fact, now that I read the statement more carefully, I disagree with it - either that or I find its wording unclear - not sure which. This advocates using procedure declaration statements instead of external because "this allows the interface to be specified in the same place". If you are talking about the full interface for something declared in a procedure declaration statement, then that can only be declared in an abstract interface block, which is not "the same place" (as the procedure declaration statement), though it is "all in one place". Plus that would give the procedure an explicit interface. And whereas I agree it is good practice to use explicit interfaces, the distinction goes far beyond just the syntactic one of specifying the whole interface in one place. If you are talking about using a procedure declaration statement to declare an external with an implicit interface, then I think it a bit misleading to say that "this allows the interface to be specified" as the only part of the interface specified is whether it is a subroutine or function, and the return type if it is a function. And in those cases, the same effect can also be achieved with the external atttribute on a type declaration, as in real, external :: f One might argue that there are advantages to procedure (real) :: f but any advantages would have nothing to do with one form specifying more in the same place than the other. My reworded version just points out that the external attribute may also be conferred by a procedure declaration statement or by an external attribute in a type declaration statement. I avoid making any explicit value judgement. [208:37+] I added the word "function" to the constraint. It is always explicitly declared whether a procedure pointer is a function or a subroutine, so might as well at least require compile time diagnosis of that discrepancy. Likwise, I added "subroutine" to the constraint at [208:39+]. And start both constraints with "The". [209:31+] 'Tis a little strange that this is going to end up with a section that has examples of the less common case (references to procedures via pointers) but does not have examples of the simple case. But not strange enough that I took the time to do anything about it. Note that I had to study several of the edits in this paper to figure out what I was being instructed to do. Please give me all edits as actual instructions in English. Just giving a page and line reference like, for example, [212:27-41] is not enough. Tell me what to do with those lines. Should I replace them with the new material, insert the new material after them, or what? You needn't be very wordy, but just something like "Replace [212:27-41] with" or "Insert after [xxx:xx]", or something of the sort. I don't like having to read the referenced material and compare it to the edit to decide whether this looks like it was intended as a replacement or an addition. [212:27-41] The proposed title for this section is too long. Section titles really need to fit on one line. This one overflows and Frame makes a mess of the result. I don't want to have to figure out how to fix up the mess. Much easier to just shorten the title. I changed "dummy procedures or dummy procedure pointers" to "dummy procedure entities", which shortens it enough. In the first reference to a dummy argument, always use the indefinite article "a". Only in subsequent references to the same dummy argument do we switch to "the". I.e. start with "If a dummy argument..." instead of "If the dummy argument...." The proposed wording for the 3rd paragraph is at best incomplete, and possibly wrong. The wording in 12.3.2.2 is much better. The word "explicitly" there is vital to the whole point; and also one version mentions the explicit interface case. Aha. Inspiration strikes. I'll just move the relevant sentence from 12.3.2.2 to here. It is really out of place in 12.3.2.2 anyway. It is discussing requirements for actual arguments, so it fits in 12.4.1.2 perfectly. Section 12.3.2.2 is on the EXTERNAL statement, which is now only one of quite a few different ways to specify the EXTERNAL attribute and is a strange place to bury a requirement that need not involve the EXTERNAL statement at all. (In f77, the EXTERNAL statement was the only way to specify the EXTERNAL attribute, but no longer). As mentioned above, I find the bit about "having an interface to a pure procedure" to be a bit wordy. Stuck closer to the orginal wording here, just changing "procedure" to "argument" in a few places - that's the only change really relevant; the rest of the proposed changes in the paragraph are just a rewording (and I like the original better). I think the rewording in the 5th and 6th proposed new paragraphs makes an inadvertent (I assume) incompatability with f77/f90/f95. I went back to the old wording, just adding "function procedure pointer" and "subroutine procedure pointer" to the possibilities for the actual arguments. The incompatability is that the f90/f95 version allowed a dummy procedure to be passed as an actual argument in cases where it was not known whether the dummy procedure was a subroutine or a function. At least I think that was allowed. In any case, by keeping the original wording, I avoid any question of incompatability. Again, the point here is to just make the changes actually relevant to procedure pointers instead of rewording the whole thing. [242:18-22] I did minor rewording that I thought made it arguably less awkward. [242:26+] All the other cases here are distinguished in terms of TARGET instead of POINTER. Reworded the new ones to correpond. And if TARGET is a procedure or procedure pointer, then we already have that POINTER is required to be a procedure pointer, so we don't need to include that in the case condition. And if we didn't know that, then failing to include a case for it wouldn't establish the requirement - it would just leave the result unspecified by the standard. Likewise, I don't see the point in elaborating all the kinds of procedures that target might be as part of the distinguishing conditions for case ii - just "If TARGET is a procedure" is fine. The "if" conditions here are used solely to distinguish between the cases - if something doesn't contribute to that distinction, then it doesn't belong as part of the initial "if" clause for the case. Also, do add the "is present" condition to both "if" tests. That *IS* needed, just like in all the other cases except for case i. paper 98-122r1, partial edits for pdts [xv:14] is really [xv:41] ([xv:14] was relative to 97-007r1). "generic overload resolution" -> "generic resolution" in the note in the new section 4.2. Floor amendments suggested one such change above, but in revising 98-122 into 98-122r1, I missed this second case of the same phrasing. While in the area, slightly simplified the organization of the former section 4.3. Eliminated the section heading for 4.3.1, Numeric types, merging its paragraph into 4.3. Eliminated both the section heading and the body of 4.3.2, Nonnumeric types. (The 2 sentence body didn't actually say anything, but was evidently just filler to keep the section from being empty). Promoted all the subsections up one level. Hyphenate "derived-type entity" in the para added at [37:39]. Singularize the para formerly at [38:27]. Hyphenate new "Derived-type parameters" heading. Change "point" to "general_point" in the note 4.new1 and the reference to it. This avoids confusion with a different type named "point" in previously existing examples. paper 98-123, public entities of private type. Done with no changes. paper 98-131r1, complex constants As suggested in the floor discussion, I added an extra example in note 4.10. It looks to me like we could now simplify both the real and imaginary part to just "constant" instead of listing the three separate possibilities. (And we'd also then change the constraint to say "constant" instead of "named constant"). But I didn't yet do this - just a suggestion for improvement. paper 98-134r2, derived type I/o Hyphenate user-defined everywhere. Hyphenate "derived-type" when used as an adjective (which is most, but by no means all, places). Several other hyphenation changes. Deleted quite a few commas, which were a bit over-used. Use lower case in heading 9.4.4.3. "section 9.4.2" -> "9.4.2" (ISO style guide). ", as described in section 9.4.4.4.3," -> "(9.4.4.4.3)" several times. "visible" -> "accessible" twice. (Same terminology used elsewhere). "will" -> "shall" some places. "Except when" -> "Unless" a few times, and one "when" -> "if". (Avoid using "when" unless time is involved). Added several of the exception clauses added in 9.4.2 and 9.4.4 at the end of the sentences instead of the beginning, except for one case, which didn't parse well that way. (Generally better to put exceptions after the general rule if it "works"). Also, "object" -> "list item" in these exceptions because 9.4.4.4.3 talks about processing list items, not objects. Reorganized the sentence defining "child data transfer statement" so that my brain could parse it. In the process, eliminated the word "other" and changed it to reference "a" parent instead of "the" parent. Unless I am reading things wrong, a data transfer statement may be both a child and a parent and there may be multiple parents active at a given time. I think the former wording implied otherwise - particularly the "other". Ah. Yes, I see the note right after says that I have the right concept; I think this wording is in better agreement with the note. Fixed some list syntax. In the new section 9.4.4.4.3, did some rewording along the following lines: Use "shall" instead of "will"; these statements are placing requirements on the processor; "shall" is the ISO-preferred form for stating requirements. Similar introduction of "shall" elsewhere to make it explicit that these are requirements, not just notes. And make it explicit that these are requirements on the processor, rather than on the program. We do say in section 1.6 that requirements apply to programs except where stated otherwise. Several of the requirements in this section don't make any sense if applied to the program (how could the program ensure that it got passed an argument with the right value). The intent is reasonably clear, but it would be better to make it explicit like 1.6 says we do. I probably missed some cases of this (seems like I'm always short of time any more), but I fixed it where I noticed. Just refer to argument values rather than dummy argument values. If we were to be more specific, it would make more sense to talk about the actual argument values than the dummy ones. The dummy arguments get their values from the actual ones by the usual argument association process. We don't want to imply that there is something different here that makes the dummy arguments "magically" get values by some mechanism other than association with an actual argument. The term "unit value" is subject to misinterpretation; reworded to refer to the value of the unit number. We defined the term "parent data transfer input/output statement", so lets use it instead of introducing the different term "originating input/output statement" for the same thing. Avoid wording that needlessly refers to syntax instead of semantics. Specifically instead of "if the parent data transfer statement contained a " say "if the parent data transfer statement specified namelist formatting." We don't care about the syntax used for the specification - just that this is what it specified. Also makes the wording more parallel because the corresponding case for list-directed didn't talk about a * for the unit number; it just said list-directed. Also, I made terminology more consistent by always saying "specified list-directed formatting" instead of randomly switching to "was a list-directed input/output statement." Avoid using "contain" in several contexts. Variables don't "contain" values - they "have" values. The "(e.g FORMAT(DT12.5.2)" doesn't add anything to "the edit descriptor", so I omitted it. To make it actually a useful example, it would need to say that the 12, 5, and 2 are the values of w, d, and m. "arg[s]" -> "argument[s]" several times. Several things in description of "err/errmsg" arguments. Things don't happen "when" it is set to true. The subroutine is quite free to set it to true internally with no special effect. It is only if it returns a value of true that things happen. I don't understand what it means for the standard to state as a requirement that the processor shall "attempt" to do something. I assume that the processor is actually required to do it. If not, then this is perhaps appropriate for a note about what might happen, but not as normative text stating a requirement. I took out the "attempt" part. If this isn't the right fix, let me know. For errmsg, use the same kind of terminology as we use for stop and pause; that the processor shall "make the value available." Saying that the processor shall "output" the value invites questions about where it has to output it. Since we are talking about an i/o operation in the first place, there is an obvious possible answer that I'm sure is not what is intended (output to the file specified by "unit"). Add apostrophies in a few posessives. "other external unit other" -> "external unit other" Singularize several conditions. "READ" -> "read" when not specifically used as a keyword. ***ACTION FLAG 1 The exception to allow recursive internal i/o is specified too vaguely. It invites interpretation requests as to what situations do or do not fall under the exception. My personal opinion is that the best way to handle this is to allow recursive internal i/o allowable in general - then there is no exception to define the boundaries of. There have been numerous requests for this feature anyway. But this would be far beyond an editorial change, so I'm just calling it to J3's attention. The proposed wording says "When a parent input/output statement is active, data transfer input/output statements that specify an internal file are permitted." As best as I can tell, this means that the following code is legal if a parent input/output statement is active, but not otherwise. ... character :: string*8 external f write (string,*) f() ... character*8 function f() write(f, *) 'hello' end (ok, this code is stupid - but it was the shortest thing I could write to illustrate a question that does regularly come up). This discrepancy is going to be hard to explain. Or if this isn't what the quoted words mean, then the words aren't very clear. ***END ACTION FLAG 1 Use the same terminology in restricting OPEN, CLOSE, et. al. as used for the other restrictions right above. The other restrictions talk about parent data transfer statements being active instead of about a user-defined derived-type i/o procedure being active. I don't see any reason for the sudden change in phraseology. "such as ... etc" is redundant. Delete the "etc." Avoid unnecessary dependence on syntax. Specifically, Just say that an i/o statement shall not be asynchronous; don't talk about the asynchronous="yes" specifier. And all of the words about being in procedures invoked directly or indirectly from a derived-type i/o procedure can be simplified to "child". Thus the whole para about disallowing async becomes just "Neither a parent nor child input/output statement shall be asynchronous." "ex." isn't a widely-accepted abbreviation. "e.g." would be ok, but I just spelled out "for example" instead. "letters" -> "letters" several times. "corresponds with" -> "corresponds to" In 10.5.5, we don't need to specify "the user shall" because we have the general rule that requirements are on the program (user) unless stated otherwise. I added the "optional" para into the introduction where we talk about new features, but I haven't redone any of the words around it. All the rest is still talking about what was new in f95. paper 98-135r2, command line args I did a very hasty and sloppy job on this one. I don't think some of the details hang together quite as well as they ought to, reflecting the fact that it was thrown together pretty quickly and yet introduces some new fairly substantial concepts - like these new kinds of variables that are sort of like dummy arguments but aren't actually dummy arguments. I don't think you can introduce such a new thing quite this simply without missing some issues. Someone else can fix the fine points and interp requests if desired. Interp requests like whether these things can be module variables, or in common, or equivalenced to. For dummy arguments, the answers would be "no." But these quite explicitly are not dummy arguments. (Smart move, that - it avoids having to make them fit into all of the interactions between dummy and actual arguments). I don't see any restriction against any of the above (they aren't attributes, so saying that the variables can have no other attributes doesn't do it). And I can see a use for putting them in modules (saves allocating and making a copy). Dunno whether you want to allow that, but if it isn't clear, someone is going to try it and then ask why it doesn't work (or why it works on one compiler but not another). I keep having a feeling that lots of users are going to look at this feature and say 1. I can't do anything like that right now (can only be done by the compiler), so I'll keep using getarg (or whatever). 2. And this doesn't work as well for me as getarg (either because the main program isn't in F2k or because the args are wanted without mods to the main program), so I'll insist that my vendor support both this (to be standard-conforming) and getarg. Oh well... I'm tired of the whole thing. [53:12] and [57:42] "" -> "program argument". Why arbitrarily use an English term on one side of the "or" and a bnf term on the other? Either way is ok, but the inconsistency looks odd. [57:42] The comma is gramatically wrong. But the sentence is hard to read without it. Should be reworded, but I didn't bother. Section 11.1.1 I find it amusing that we feel it necessary to say in normative text that the meaning of the term "delimiter" is processor dependent. This might be slightly less amusing if the term "delimiter" appeared anywhere else in the edits. Given that it doesn't, I deleted this statement about it (but left the parts about command line, command line argument, and command name). "actual name" -> "name". Or do you really want people thinking that "actual name" would have something to do with an actual argument? "only one" -> "no more than one". Or someone is going to interpret this as saying that all of the arguments are mandatory. "each" -> "a given" I find it minorly odd that these variables are all essentially INTENT(INOUT). Though we don't allow that to be stated explicitly, that's the way they act, unless I'm misreading it. I see no restriction against redefining them. My intuition would have thought they would be INTENT(IN). Nothing really wrong, just doesn't match my mental model well. Obviously a defect in my model, as supported by the fact that my model has a really hard time swallowing the concept of matching arguments by type and rank instead of either name or position. This places limitations that we may regret someday. I don't like saying "The xxx argument contains...". Changed these words to something more like "The value of the xxx argument is...". Well, I changed some of them. Left others alone because I got tired of figuring out to reword them. At least added some articles so that sentences don't start with the lower-case variable names. Some "will" -> "shall" ; "which" -> "that". ***ACTION FLAG Do we really want to have the requrement that LEN(command_line)>=1 (and the same for the args)? I put it in as shown but I think it is a mistake. This seems completely arbitrary. We have perfectly well-defined zero-length strings, and it is perfectly meaningful for a command line or argument to be zero length. Next thing you'll be telling me we should make DO loops always have trip counts of at least 1. Note that if we put this in like this, then changing it later is an incompatable change (because user code could legally have hardwired references to the first character of the string). It is also really confusing when we have the statement that "the length of an element of argument_text shall be at least one" and later say that a zero value of argument_length might indicate that the argument was zero length. Yes, I understand the distinction being made, but I still find it confusing. I'd think it would be a lot easier to drop this arbitrary restriction than to explain it. But this is the way it passed, so I'm leaving it alone. I added a J3 note as a reminder. I you think its just fine as is, then the J3 nore can be deleted. ***ACTION FLAG Also, the above requirements on the processor are in the middle of several requirements on the programmer. We ought to make this distinction more clear, but I left that aspect alone also. Combined some adjacent notes. I cannot fathom what the note "Various user interfaces, including test and graphical user interfaces, may process the command line" is supposed to mean. I just typed in in as is, but I can't imagine that it is sufficient to clarify anything. I suppose it might be intended to mean one or both of "The command line passed to the program might not be exactly what the user typed because it might have been processed before passing it to the program" or "The command line passed to the program might be a textual representation of a gui command." But the only way I came up with those is by thinking of things that might be appropriate to say in a note; I didn't get there by interpreting this note. The first sentence of the description of argument_text makes it sound the same as command_line. I gave up on rewording it. And the "after" wording in "i'th argument after the command name" is a bit specific about implying a physical ordering on a command line (as opposed to some other mechanism for defining arguments), but I didn't do anything about that either. I deleted the false statement about the "last" argument. (Try it for the case when there are 0 arguments - a valid, and even common case). Since the statement didn't appear to say anything necessary anyway, I didn't bother to try rewording it. The only thing I got from the statement that didn't follow as a direct conclusion from the sentence right before it was that size(argument_text) is the number of arguments plus 1. If that is supposed to be the message, it is easier to say directly. I wonder whether the lower bound that is required to be zero has to be a literal 0 or whether it can be any specification expression that evaluates to 0. Why anyone would put anything other than a literal 0 I don't know, but I can't find this requirement clarified. My best guess is that it could be any specification expression that evaluates to 0. Also makes me wonder why we have such a restriction at all. Is it just to make the words of the standard easier to write? The "usual" treatment of "real" dummy arguments would imply that we don't care what the lower bound is - lower bounds other than 0 would just offset the index values correspondingly. I left this alone, but I see an interp question lingering here. If there is any difference in context between "LEN(argument_text(0)) shall always be at least one" and "An element of argument_text shall always be at least of length one" I can't see it. This doesn't seem like the appropriate place for a reminder that all elements of a character array have the same length if that was supposed to be the point. I deleted the second of these. "arg_text" -> "argument_text" several times. Several of the expressions that are written in Fortran should probably be in English instead when they are in an English sentence, but I didn't bother. (Things like SIZE(...) and LEN(...)). I think it a bad idea to use the term "present" when we are talking about the arguments being long enough to contain everything instead of about argument presence, but I left it alone. Hmm, we have 3 different meanings of "present" used here: a character being present in a string, a program_argument variable being present in the program statement, and an actual program argument being present in the operating environment. None of these, by the way, are the same as the concept tested by the PRESENT intrinsic. Oh well. I can't find any normative text to support the statements made in notes about the meaning of 0 values of argument_length. So I made these statements normative instead of notes. Its going to be a little tricky to declare all of these arguments without using any attributes except for optionally TARGET. :-) I added "not listed above".