Poll: Fortran 202X Conditional Expressions syntax

I disagree that this is a completely unnecessary change. I use conditional expressions all the time in other languages and back when I first learnt Fortran it was probably the first feature I was surprised didn’t exist. Just because it isn’t strictly needed doesn’t mean it isn’t a useful enough feature to warrant adding. Array constructors aren’t needed, but can you image writing Fortran without them?

1 Like

I admit I may be missing something, but why can’t we have the standard ternary syntax as in C++ and almost every other language?

condition ? exprIfTrue : exprIfFalse
6 Likes

I vote other, prefer c++ syntax

1 Like

The basic issue here is to have a mechanism to specify short-circuiting the evaluation of a logical expression. For example,

if (present(x) .and. x > 0.) then …

You don’t want the x > 0. part evaluated if x is not present. (Assuming x is a dummy argument here.)

Some compilers already implement algorithms to partially do this. For example, in a logical expression,

  1. Always evaluate references to the PRESENT intrinsic first, if they appear. If that result is sufficient to determine the value of the whole expression then quit. (Hence the short-circuit name. In the example (Present(x) .and. x < 0.), if Present(x) is .false. then skip trying to evaluate x < 0.) This a common case, and evaluation of Present(x) is cheap.

  2. Evaluate parts of the expression that do not involve references to functions (other than Present) first, and if that is sufficient to determine the result, then quit - and don’t do the (usually) expensive function evaluations. (Note that this an lead to unexpected results if the user assumes the function references are evaluated and those evaluations have side effects.)

Because of 2 there are usually compiler options to control how much short-circuiting occurs.

4 Likes

As someone who attempts to be a multi-language programmer, if you are going to add this feature I would prefer that it not be “almost but not quite” the C/C++ syntax. That is just one more detail I would have to memorize when “code switching” (a linguistics term but seems particularly appropriate here) between languages and I’m already typing if (cond): far too often in Fortran. The first form looks like Fortran (and also like a Python list comprehension, which may be an advantage or disadvantage). Yes it’s more typing, but if you are programming in Fortran you already accept it’s more typing than C/C++ in general.

5 Likes

None of these seem particularly Fortran-esque. The ? form appears nothing short of completely unreadable, and the arrow form introduces a different arrow operator than the one Fortran already uses for pointers (among other things). The keyword one is maybe the only one that looks even remotely reasonable, but I still don’t think it is a good solution.

6 Likes

I personally like the idea to expand the intrinsic merge function to support this kind of operations. It feels more fitting for Fortran for the ternary operator to also natively support operations on whole arrays. I’m not sure how well this works in the context of the proposed conditional expressions.

1 Like

I voted other. Prefer the c++ style.

These all look messy and very human unreadable. Is the change really necessary?

5 Likes

Welcome and thank you @DavidMcP, @mkonecny, @kaholcomb, and @AndyM!

4 Likes

Such a feature would be highly desired. It happens so frequently that I miss it almost daily.

1 Like

I voted for both expression form and “?” form. Finally the ternary conditional operator arrives!
IMHO the arrow form can get confused with pointer assignments…

1 Like

Pointer assignment uses => so the syntax parser can distinguish that from ->. But I agree that it could be visually confusing.

First, I will direct people’s attention to ?: - Wikipedia which lists languages that have some sort of conditional expression feature. There are a lot, and the majority use ? in some form or other, though a couple (such as Ada) use a keyword form.

I am torn between the keyword form and the ? form (which Malcolm refers to as “line noise”.) The keyword form seems most Fortran-like, though it is verbose. The ? form is more like what other languages use and might be viewed more favorably by those who come to Fortran from elsewhere. Either one would be acceptable to me.

The arrow form is largely unfamiliar and reuses syntax from elsewhere in the language. I would not find that acceptable. I do think we should add this feature, as it is a popular request.

5 Likes

The ? form as proposed is not like in other languages. The C++ form is:

result = a > b ? x : y

while the proposed Fortran ? form above is:

result = (? a > b ? x :? y ?)

The feedback above is clear: the proposed ? Fortran form is very unpopular, and from the comments it seems unpopular because it is similar, but different to how it is done in other languages that use the ? form, and also a lot more noisy (4x as many question marks). With 68 people who voted so far, only 8% would prefer the ? form.

We can go against the popular vote if we truly believe in the committee that some feature would lift the language up and that the popular vote is not the best wisdom for Fortran. Absolutely.

In this case I would argue this feature is not it. Let’s not do the ? form as proposed above. Rather, let’s choose some of the other more popular alternatives above.

5 Likes
result = (? a > b ? x :? y ?)

I would call it a syntactic abomination. In the C form, there is one ? which has a clear meaning: does a>b ? Here, on the four, three are just some kind of separators or tags, but really not elegant as they need to be coupled with a second character.

In C, you can still understand quite quickly the following expression:

result = (( a > b ? x : y ) + ( b > c ? z : u )) < d ? p : q ;

But in that proposed Fortran form?

result =(? ((? a > b ? x :? y ?) + (? b > c ? z :? u ?)) < d ? p :? q ?)

OK, it’s not worse than a regular expression, but…

7 Likes

I have just submitted a PR for an intrinsic function approach:

@mleair, @milancurcic, @zjibben, @pmk, @awvwgk and others who mentioned you would maybe like to expand merge or add a new intrinsic, can you please help me finish this PR? Let’s see if we can make this a viable proposal.

1 Like

I voted “Other”.

I think a Fortran-like and simpler syntax is better. The following syntax has an affinity with existing Fortran syntax:
if(cond) a else b
if(cond) a elseif(cond2) b else c

or a function-call-like syntax, extending merge() and changing the order of arguments:
ifelse(cond, a, b)
I have already seen this defined as a macro:
#define ifelse( cond, x, y ) merge( x, y, cond )

It would be great to use the select case more flexibly; perhaps this is a minor opinion.

2 Likes

Is ?(a>b,x,y) feasible? An argument against ifthen(a>b,x,y) is that ifthen looks like a normal function name, and Fortran functions evaluate their arguments. Using ? would emphasize that it is not a normal function and would remind people of C and C++.

5 Likes

If and when one of these syntaxes is chosen, will it be useable in regular if statements? Because it looks like that would provide a workaround for the lack of short-circuiting .and. and .or..

e.g. the (incorrect) code

if (present(x) .and. x>0) then

could be written (correctly) as one of

if (if (present(x)) then x>0 else .false. endif) then

if (? present(x) ? x>0 : .false. ?) then

if (present(x) -> x>0 : .false.) then

if (ifthen(x, x>0, .false.)) then

I can see this being a more common use case than the use in function arguments.

If this is allowed, it might be worth considering what the default behaviour is for one of these expressions without an else clause. e.g. if the default evaluates as .false. this would allow a simplification to one of

if (if (present(x)) then x>0 endif) then

if (? present(x) ? x>0 ?) then

if (present(x) -> x>0) then

if (ifthen(x, x>0)) then
1 Like