To: J3 J3/21-162r1 Subject: Conditional expressions and arguments - edits From: Malcolm Cohen Date: 2021-June-30 Reference: 18-274, 20-142, 21-157r2. 1. Introduction This paper contains the edits for conditional expressions and conditional arguments. For background, please see 18-274. For formal specifications, please see 20-142. For syntax, please see 21-157r2. Note that section 4 will be applied only if the so-called "previous form" of conditional arguments is selected for the syntax. 2. Edits to 21-007r1 for conditional expressions (only) [xiii] Introduction, Data usage and computation bullet, append "Conditional expressions provide selective evaluation of subexpressions" [47:10] 6.2.1 Tokens, p1, after "..," insert "?," making that whole sentence read "A lexical token is a keyword, name, literal constant other than a complex literal constant, operator, statement label, delimiter, comma, =, =>, :, ::, ;, .., ?, or %." [149:26+] 10.1.2.2 Primary, R1001 primary, add new production "<> " [150:1-] Before 10.1.2.3 Level-1 expressions, insert new subclause (note: angle brackets omitted in the BNF as all lowercase is either bold (is/or) or italic (BNF terms). "10.1.2.2a Conditional expressions A conditional expression is a primary that selectively evaluates a chosen sub-expression. R1001a conditional-expr is ( scalar-logical-expr ? expr [ : scalar-logical-expr ? expr ]... : expr ) C1003a Each of a shall have the same declared type, kind type parameters, and rank. NOTE 1 Examples of a conditional expression are: ( ABS(RESIDUAL)<=TOL ? 'ok' : 'did not converge' ) ( I>0 .AND. I<=SIZE(A) ? A(I) : PRESENT(VAL) ? VAL : 0.0 )" {The opening paragraph is mere witter to introduce the syntax.} {Note the constraint says " of" not " in", so we know which expressions it applies to. If that's too subtle we could introduce a new syntax term, but I think it is reasonably understandable as is.} {I think the last example will fit on one line in the standard.} [155:17+] 10.1.4 Evaluation of operations, end of subclause (after p5), insert new paragraphs "Evaluation of a evaluates each in order, until the value of a is true, or there are no more s. If the value of a is true, its subsequent is chosen; otherwise, the last of the is chosen. The chosen is evaluated, and its value is the value of the conditional expression. The declared type, kind type parameters, and rank of a are the same as those of its s. The dynamic type, length type parameters, and shape are those of the chosen . A is polymorphic if and only if one or more of its s is polymorphic. NOTE 3 Only one of a conditional expression is evaluated, and any of its s subsequent to one that evaluates to true are not evaluated." 3. Additional edits to 21-007r1 for conditional arguments [xiii] Introduction, Program units and procedures bullet, append "Conditional arguments provide actual argument selection in a procedure reference." [47:10] 6.2.1 Tokens, p1, before "operator," insert ".NIL.," making that whole sentence read "A lexical token is a keyword, name, literal constant other than a complex literal constant, .NIL., operator, statement label, delimiter, comma, =, =>, :, ::, ;, .., ?, or %." [315:26+] 15.5.1 Syntax of a procedure reference, R1524 actual-arg, after "<> proc-component-ref" insert new production "<> " [316:4] C1535 replace "(R1524) shall not be a variable" entirely: "C1535 An that is an shall not be a variable or a ." {NOTE: This is a disambiguating constraint, not a "the processor must check this" constraint.} [316:7+] After the last constraint in this subclause (C1537), insert new BNF and constraints. "R1525a conditional-arg is ( scalar-logical-expr ? consequent [ : scalar-logical-expr ? consequent ]... : consequent ) R1525b consequent is consequent-arg or .NIL. R1525c consequent-arg is expr or variable C1537a Each of a shall have the same declared type, and kind type parameters. C1537b Either all s in a shall have the same rank, or be assumed-rank. C1537c At least one in a shall be a . If the corresponding dummy argument is not optional, .NIL. shall not appear. C1537d If its corresponding dummy argument is INTENT (OUT) or INTENT (INOUT), each in a shall be a variable. C1537e If its corresponding dummy argument is allocatable, a pointer, or a coarray, the attributes of each in a shall satisfy the requirements of that dummy argument. C1537f A shall not be assumed-rank unless its corresponding dummy argument is assumed-rank. C1537g A that is an shall not be a variable. C1537h In a reference to a generic procedure, each in a shall have the same corank, and if any in a has the allocatable or pointer attribute, each shall have that attribute." {C1537f might be inferred from C838, so could be unnecessary.} {NOTE: C1537g is another disambiguating constraint.} [318:1-] Immediately before 15.5.2.3 Argument association, insert subclause "15.5.2.2a Conditional argument correspondence If an is a , each is evaluated in order, until the value of a is true, or there are no more s. If the value of a is true, its subsequent is chosen; otherwise, the last is chosen. If the chosen is a , its or is the actual argument for the corresponding dummy argument, and if it is an , it is evaluated. If the chosen is .NIL., there is no actual argument for that dummy argument. Each in a shall satisfy any requirements of the dummy argument on declared type, kind type parameters, attributes, and properties that do not depend on evaluation of the or any contained expressions. The declared type, kind type parameters, rank, and corank of a are those of its s. It has the ALLOCATABLE or POINTER attribute if and only if all of its s have that attribute. It is polymorphic if and only if one or more of its s is polymorphic. NOTE 1 An example of conditional arguments in a procedure reference is: CALL sub( ( x>0 ? x : y>0 ? y : z ), & ( edge>0 ? edge : mode==3 ? 1.0 ), & some, other, arguments)" {I omitted the stuff about not evaluating non-chosen things, as that would just complicate the description without saying anything new. A note could be added if thought useful.} {We could add these paragraphs to 15.5.2.1 Argument correspondence instead. That subclause is one giant indigestible paragraph though, which would warrant serious wordsmithing if we're going to add anything more.} {The penultimate paragraph is to enforce things like "allocatable dummies require allocatable actuals" without listing them all.} {The last paragraph is there for generic resolution, which needs to know these things. It's not necessary for a specific procedure reference as the actual argument is the chosen consequent-arg, not the conditional-arg itself.} 4. Differences to the edits for the previous form of conditional arguments Omit the extra edit to [47:10]. The BNF is: "R1525a conditional-arg is ( scalar-logical-expr ? consequent-arg [ : scalar-logical-expr ? consequent-arg ]... [ : else-consequent-arg ] ) R1525b consequent-arg is expr or variable R1525c else-consequent-arg is consequent-arg" Constrain C1537c is different: "C1537c If its corresponding dummy argument is not optional, shall have an ." The first two paragraphs of 15.5.2.2a Conditional argument correspondence are: "If an is a , each is evaluated in order, until the value of a is true, or there are no more s. If the value of a is true, its subsequent is chosen; otherwise, if appears, its is chosen. If a is chosen, its or is the actual argument for the corresponding dummy argument, and if it is an , it is evaluated. If no is chosen, there is no actual argument for that dummy argument." The example is changed to: "CALL sub( ( x>0 ? x : y>0 ? y : z ), & ( edge>0 ? edge : mode==3 ? 1.0 ), & some, other, arguments)" ===END===