To: J3 J3/18-274 Subject: If-then or else From: Malcolm Cohen Date: 2018-October-16 1. Introduction Various proposed features for "conditional and" functionality and similar were proposed for Fortran 2008, but failed due to lack of consensus as to whether these should be functions or operators. This paper suggests reconsideration; for syntax we should avoid either function or operator syntax in favour of keywords, since these are not really functions. 2. Motivation People have wanted to write things like IF (I on the right-hand-side of a pointer assignment. This does not have a big bang for the buck, but does not seem terribly problematic. 4.2 Definitely not requirements Procedure pointers are adequate for conditionally passing procedures (or not), and alternate returns are obsolescent, therefore the conditional argument form need only handle data objects. Similar considerations imply that the conditional expression form also need only handle data objects. 5. Syntax ::= IF ( ) THEN ( ) [ ELSE IF ( ) THEN ( ) ]... ELSE ( ) END IF A is a primary. The syntax can be disambiguated from that of a function reference as soon as the "THEN" keyword has been seen. Constraint: Each in a shall have the same declared type, kind type parameters, and rank. ::= IF ( ) THEN ( ) [ ELSE IF ( ) THEN ( ) ]... [ ELSE ( ) ] END IF ::= | (Comment: If we do nesting, the BNF would have "| " appended to it.) A is an actual argument (). Constraint: In a , each or that is a shall have the same declared type, kind type parameters, and rank. Constraint: If the corresponding dummy argument is not optional, the ELSE clause shall appear in the . Constraint: In a that corresponds to an INTENT(OUT) or INTENT(INOUT) dummy, each shall be a . (Comment: In other cases we want to allow some of the consequent-args to be variables and others to be expressions, as we would not want to be forced to copy a big array variable.) Constraint: If the corresponding dummy argument is allocatable, a pointer, or a coarray, the attributes of each shall satisfy the requirements of that dummy argument. This is to eliminate the possibility of an argument mismatch error at runtime depending on the results of the s. The wording permits a consequent argument to be a pointer, allocatable, or have corank indepently of the other consequent arguments but not independently of the dummy argument. Constraint: 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. This retains generic resolution at compile time. 6. Alternative syntax discussion Firstly, some design principles: (a) it should be visibly different from function syntax, because it is not a function; (b) it should be visibly different from operator syntax, because it is not an operation; (c) the difference should be "near the front" of the conditional expression so as to simplify parsing by computers as well as humans; (d) it should nest unambigously, and any parentheses needed should be part of the syntax (otherwise the "variable" case cannot be nested); (e) it should be readable & Fortran-like and not like line noise, -- readability is self-evidently desirable. Both (a) and (b) are desirable because (i) this does not follow the usual "evaluate the arguments/operands and call the function/do the operation", (ii) we do not want to affect operator priorities, and (iii) we do not want to invade the user namespace unnecessarily. Some possible (and some have actually been proposed) examples: (1) ? : satisfies (a)-(c), but not (d) or (e); (2) (? : : ?) satisfies (a)-(d), but not (e); (3) (? | : ?) satisfies (a)-(d), but is even worse on (e); (4) .ANDTHEN. .ORELSE. satisfies (a),(c),(e) but not (b) or (d), and only provides short-cut logical conditions, not general selection; (5) .IF. .THEN. .ELSE. .ENDIF. satisfies (a), (b), (d), but not (c) and is weak on (e). The "line noise" versions (2) and (3) are not definitive. I chose to put question marks to draw the distinction between the syntactic grouping (? ... ?) and ordinary parentheses (which turn variables into expressions). Other line noise variations are certainly possible if preferred. (It should also be noted that line noise does not do missing optional arguments very well, nor "ELSEIF" style chaining, so more work would be required if we choose that syntax.) The ordinary keyword form suggested in section 5, while more verbose than some of the above, best satisfies the design principles. 7. Semantics Evaluating a or selects an or by evaluating each in turn until one of them is true, or the ELSE or ENDIF clause is reached; the corresponding or , if any, is the one selected. The declared type, type parameters, and rank of a or is that of the s or s that it contains. The value of a is the value of the selected . If evaluating a selects no or , there is no effective argument associated with the dummy argument. Otherwise, the selected or is the effective argument. All static requirements from a dummy argument on effective arguments apply to any , for example if coindexed objects are prohibited as an actual argument they are also prohibited as a consequent argument. This will need additional wording in the standard. 8. Estimated impact The impact on the standard is relatively minor, but more than a simple intrinsic function. The impact on implementations is probably minor, but certainly not trivial. ===END===