# 202X feature: Conditional Expressions

**URL:** <https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329>\
**Category:** Uncategorized\
**Created:** [October 5, 2020, 12:35pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329 "2020-10-05T12:35:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 5, 2020, 12:35pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/1 "2020-10-05T12:35:34Z")

</div>

The Fortran Standards Committee is considering proposals for “Conditional Expressions”. An example:

Original code:

```auto
  IF (PRESENT(D)) THEN
    CALL SUB(A,B,C,D)
  ELSE IF (X<1) THEN
    CALL SUB(A,B,C,EPSILON(X))
  ELSE
    CALL SUB(A,B,C,SPACING(X))
  END IF

```

One proposed syntax is “keyword syntax”:

```auto
CALL SUB(A, B, C, IF (PRESENT(D) THEN D ELSE IF (X < 1) THEN EPSILON(X) ELSE SPACING(X) END IF)

```

The second proposed syntax is “? syntax”:

```auto
CALL SUB(A, B, C, ? (PRESENT(D) D :? (X < 1) EPSILON(X) : SPACING(X) ?)

```

I would like to encourage the wider community to leave feedback on this regrading which is more readable or what the committee should do at [https://github.com/j3-fortran/fortran\_proposals/issues/183](https://github.com/j3-fortran/fortran_proposals/issues/183)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 5, 2020, 5:17pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/3 "2020-10-05T17:17:25Z")

</div>

@kargl, thank you. I personally also don’t like either of the options. But I want to get as much feedback on this from the community as possible, so that I can relay the feedback to the committee. Here is the proposed syntax, I hope I translated the example correctly:

```auto
<conditional-expr> ::= (? <scalar-logical-expr> | <then-expr>
                       [:? <scalar-logical-expr> | <elseif-expr>]...
                       : <else-expr> ?)

<conditional-arg> ::= (? <scalar-logical-expr> | <consequent-arg>
                      [:? <scalar-logical-expr> | <consequent-arg>]...
                      [: <consequent-arg>]
                      ?)

```

Perhaps it is meant to look like this:

```auto
CALL SUB(A, B, C, (? (PRESENT(D)) D :? (X < 1) EPSILON(X) : SPACING(X) ?))

```

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 5, 2020, 6:55pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/5 "2020-10-05T18:55:20Z")

</div>

@kargl what you write seems to be similar to this comment to try to stick to the C convention: [https://github.com/j3-fortran/fortran\_proposals/issues/183#issuecomment-703768480](https://github.com/j3-fortran/fortran_proposals/issues/183#issuecomment-703768480)

---

<div class="post-metadata">

**Author:** ![Pompito](https://avatars.discourse-cdn.com/v4/letter/p/7cd45c/32.png) [@Pompito](https://fortran-lang.discourse.group/u/Pompito)\
**Post date:** [October 7, 2020, 3:57am UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/6 "2020-10-07T03:57:14Z")

</div>

The original form is clearer to me. People without exposure to C and little programming experience can figure out the meaning of the original code without much trouble while the C style expression needs further knowledge, and it just one more way to do the same thing. The C style expression with written keywords is just too verbose and defeats the only thing going for this which is conciseness.

I’m gonna say that although I’m not very fond of python, I do agree with the motto “Special cases aren’t special enough to break the rules” and this seems like an example of it.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 13, 2020, 4:12pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/8 "2020-10-13T16:12:35Z")

</div>

Thank you everybody for the feedback. More syntax forms are being considered:

> <https://github.com/j3-fortran/fortran_proposals/issues/183#issuecomment-707810787>
>
> Relevant papers:
> https://j3-fortran.org/doc/year/18/18-274.txt
> https://j3-fortran.org/doc/year/19/19-258.txt
> https://j3-fortran.org/doc/year/19/19-247r1.txt
> https://j3-fortran.org/doc/year/19/19-248.txt
> Taking the second example from the 18-274 paper:
> IF (PRESENT(D)) THEN
> CALL SUB(A,B,C,D)
> ELSE IF (X\<1) THEN
> CALL SUB(A,B,C,EPSILON(X))
> ELSE
> ...

  

> <https://github.com/j3-fortran/fortran_proposals/issues/183#issuecomment-707817739>
>
> Relevant papers:
> https://j3-fortran.org/doc/year/18/18-274.txt
> https://j3-fortran.org/doc/year/19/19-258.txt
> https://j3-fortran.org/doc/year/19/19-247r1.txt
> https://j3-fortran.org/doc/year/19/19-248.txt
> Taking the second example from the 18-274 paper:
> IF (PRESENT(D)) THEN
> CALL SUB(A,B,C,D)
> ELSE IF (X\<1) THEN
> CALL SUB(A,B,C,EPSILON(X))
> ELSE
> ...

At this point, using the C syntax, or the “arrow syntax” (same as C, but using `->` instead of `?`) is the most readable (from all the alternatives) that some people are actually in favor of. To be honest, I still find the “original form” the most readable, because nested conditional expressions become unreadable to me quickly.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 23, 2021, 9:55pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/9 "2021-06-23T21:55:49Z")

</div>

Just a reminder that the committee will be voting again next Monday about this:

- [Conditional Expressions · Issue #183 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/183#issuecomment-867166406)

and I still don’t like either the keyword or the ? syntax and I would recommend not to do this feature at all.

---

<div class="post-metadata">

**Author:** ![ashe](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@ashe](https://fortran-lang.discourse.group/u/ashe)\
**Post date:** [June 24, 2021, 3:01am UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/10 "2021-06-24T03:01:16Z")

</div>

An intrinsic function seems like the best solution, but failing that, why not:  
`cond .then. A .else. B` ?

It looks like Fortran because it is already syntactically valid. And you could throw in `.andthen.` and `.orelse.` for short-circuiting boolean operators.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 24, 2021, 3:08am UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/11 "2021-06-24T03:08:43Z")

</div>

Thanks for the suggestion @ashe and welcome to the forum! I have not seen this idea yet.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [June 24, 2021, 12:01pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/12 "2021-06-24T12:01:19Z")

</div>

> [@Pompito](#):
>
> The original form is clearer to me.

I agree, but the original code has logic that should be within subroutine `sub`, not in the caller. A local variable `d_` could be set appropriately. Fortran already has the ability to write `call sub(a,b,c,d)` even if `d` is not present in the caller.

IMO an unglamorous strength of Fortran is that you don’t need to be as smart to use it effectively or read it as some other programming languages, and the proposals are not in that spirit.

---

<div class="post-metadata">

**Author:** ![veryreverie](https://avatars.discourse-cdn.com/v4/letter/v/dc4da7/32.png) [@veryreverie](https://fortran-lang.discourse.group/u/veryreverie)\
**Post date:** [June 24, 2021, 1:16pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/13 "2021-06-24T13:16:56Z")

</div>

> [@Beliavsky](#):
>
> I agree, but the original code has logic that should be within subroutine `sub` , not in the caller.

I feel like the use of `if (present(x)) then x endif` is perhaps an over-simplified use case. As you say, the called subroutine can easily handle this case itself. But this stops being true if `sub` is called in multiple places, with different requirements in each case. e.g. if you had something like

```auto
function even_factorial(x) result(y)
  y = factorial(if (modulo(x,2)==0) then x else x+1 endif)
end function

function odd_factorial(x) result(y)
  y = factorial(if (modulo(x,2)==1) then x else x-1 endif)
end function

```

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [June 24, 2021, 1:57pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/14 "2021-06-24T13:57:38Z")

</div>

I use a `default` function in my codes, similar to `optval` in stdlib, that accepts two arguments, the second optional, and returns the second argument if present, otherwise the first. So I’d write the code above as

`call sub(a,b,c,default(merge(epsilon(x),spacing(x),x<1),d))`

Since `epsilon(x)` and `spacing(x)` do not require computation, this is fine. When the default values of an expression do require considerable computation, then the wordy if block is required to avoid redundant computation.

In general, Fortran does not have lazy evaluation. Would it be possible to have an intrinsic function, say `lazy_merge(x,y,true_or_false)`, that breaks this pattern and for which the compiler evaluates the third argument first and then evaluates the first or second as appropriate? This would simplify a lot of code. I guess this is just different syntax from what is being proposed?

P.S. Why does the committee use all upper case in code examples?

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 24, 2021, 1:59pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/15 "2021-06-24T13:59:51Z")

</div>

> [@Beliavsky](#):
>
> P.S. Why does the committee use all upper case in code examples?

See here: [Use lowercase for Fortran code in the standard and in proposals · Issue #56 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/56)

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [June 24, 2021, 4:00pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/16 "2021-06-24T16:00:46Z")

</div>

> [@ashe](#):
>
> … why not:  
> `cond .then. A .else. B`

> [@certik](#):
>
> … I have not seen this idea yet.

I’m under the impression syntax along the lines of `cond .then. A .else. B` was brought up a while ago during verbal discussions at a subcommittee meeting but the response was the language with its base of existing processors supporting both free-form and fixed-form source forms needed a “beginning” and “ending” set of tokens and thus came about the options of inline `if .. then .. end if` constructs and `? .. ?`, `( .. )` forms, etc…

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 24, 2021, 6:56pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/17 "2021-06-24T18:56:32Z")

</div>

We started a [poll](https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425) to collect feedback on this feature. We’ll present the results of the poll to the Committee on Monday when the proposals for this feature are due for discussion and a vote.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [June 24, 2021, 7:40pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/18 "2021-06-24T19:40:13Z")

</div>

> [@Beliavsky](#):
>
> In general, Fortran does not have lazy evaluation. Would it be possible to have an intrinsic function, say `lazy_merge(x,y,true_or_false)`, that breaks this pattern and for which the compiler evaluates the third argument first and then evaluates the first or second as appropriate? This would simplify a lot of code. I guess this is just different syntax from what is being proposed?

This is being discussed as `ifthen` in the thread cited by the OP.

---

<div class="post-metadata">

**Author:** ![ashe](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@ashe](https://fortran-lang.discourse.group/u/ashe)\
**Post date:** [June 24, 2021, 9:33pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/19 "2021-06-24T21:33:02Z")

</div>

Compilers already have to handle `cond .then. A .else. B` if there are user-defined operators named `.then.` and `.else.`. They need to be able to parse this in either source form. So I don’t see what the problem would be.

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [June 24, 2021, 9:44pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/20 "2021-06-24T21:44:29Z")

</div>

@ashe @FortranFan

IIRC, Fortran does not impose the “left-to-right” evaluation order for an expression (i.e. “terms can be evaluated in any order for maximal efficiency”), so isn’t the user-defined operators in this form not guaranteed to work as expected?

[Edit]

I guess attaching parentheses like `(cond .then. A) .else. B` may be useful, but the end result is probably the same as `merge(A, B, cond)`, in that both `A` and `B` are evaluated?

Btw I’ve played with a ternary expression and merge() below, and the latter seems to evaluate only one of `A` and `B` for gfortran-10… (but I guess this is not guaranteed to behave the same for different compilers?)

> **test code**
>
> ```auto
> // test.cpp
> #include <iostream>
> using namespace std;
> int f(int n) { cout << "(f called) "; return n * 10; }
> int g(int n) { cout << "(g called) "; return n * 100; }
> 
> int main() {
> int n;
> cin >> n;
> cout << ( n > 0 ? f(n) : g(n) ) << endl;
> }
> 
> ```
> 
> ```auto
> $ g++-10 test.cpp
> $ echo 2 | ./a.out
> (f called) 20
> $ echo -2 | ./a.out
> (g called) -200
> 
> ```
> 
> ```auto
> !! test.f90
> integer function f(n); print *, "(f called) "; f = n * 10 ; end
> integer function g(n); print *, "(g called) "; f = n * 100 ; end
> 
> program main
> integer n, f, g, ans
> read *, n
> ans = merge( f(n), g(n), n > 0 )
> print *, ans
> end
> 
> ```
> 
> ```auto
> $ gfortran-10 test.f90
> $ echo 2 | ./a.out
> (f called) 
> 20
> $ echo -2 | ./a.out
> (g called) 
> -200
> 
> ```

---

<div class="post-metadata">

**Author:** ![wclodius](https://avatars.discourse-cdn.com/v4/letter/w/87869e/32.png) [@wclodius](https://fortran-lang.discourse.group/u/wclodius)\
**Post date:** [June 25, 2021, 4:18am UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/21 "2021-06-25T04:18:33Z")

</div>

I am not happy with either form, but do like Bob Corbett’s proposed syntax in [21-159](https://j3-fortran.org/doc/year/21/21-159.txt).

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [June 25, 2021, 4:41am UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/22 "2021-06-25T04:41:27Z")

</div>

@wclodius make sure you vote in the poll please.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [June 25, 2021, 12:26pm UTC](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329/23 "2021-06-25T12:26:25Z")

</div>

> [@ashe](#):
>
> Compilers already have to handle `cond .then. A .else. B` if there are user-defined operators named `.then.` and `.else.` . They need to be able to parse this in either source form. So I don’t see what the problem would be.

First, there are sufficient differences in the semantics involved with conditional expressions, particularly with chaining, to make the analogy with user-defined operators inapplicable here. Secondly, the rules with the order of operations are fraught with so many practical difficulties, one has to bring in a beginning and ending token anyway for any deterministic usage, the tokens being parentheses.

[Next page](https://fortran-lang.discourse.group/t/202x-feature-conditional-expressions/329.md?page=2)
