Fortran standards committee approves conditional expressions

902 views
Skip to first unread message

Beliavsky

unread,
Jul 1, 2021, 11:58:24 AM7/1/21
to
See https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code example

y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )

equivalent to

if (i>=1 .And. i<=Size(a)) then
y = a(i)
else
y = -Huge(y)
end if

I think it will be a nice addition to the language, inspired by the ternary operator of C.

Jos Bergervoet

unread,
Jul 1, 2021, 12:42:04 PM7/1/21
to
Yes, we already were thaught in the 70's that for nested if's,
the code is more readable when alternating the short and long
notation.

That was with Algol68 as the teaching language, while for serious
programming Fortran was used, which at the time did not even have
the long if-then-else notation, but at least we knew how it should
have been. An now, half a century later.. finally!

(Well.. almost, that is. Still one language revision to wait for.)

--
Jos

gah4

unread,
Jul 1, 2021, 6:20:49 PM7/1/21
to
On Thursday, July 1, 2021 at 8:58:24 AM UTC-7, Beliavsky wrote:
> See https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code example

> y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )

I believe the C operator is also supposed to be the conditional operator,
but being the only ternary operator, it seems also to have that name.

Fortran has the MERGE function, which mostly works in place of a conditional operator.
MERGE does have the disadvantage in that, at least potentially, both are evaluated.

C's operator guarantees not to evaluate the wrong one, in a similar way to
short-circuit logical operators not evaluating the right operand unnecessarily.
(Both are especially convenient when there might be out-of-bounds
subscripts for array references.)

I wonder if they will now continue to add operators to replace functions,
such as the bitwise logical operations and MOD function.

Phillip Helbig (undress to reply)

unread,
Jul 2, 2021, 12:47:52 AM7/2/21
to
In article <c9c3c164-8bf9-4cd0...@googlegroups.com>,
Someone once quipped that a Fortran programmer can write Fortran in any
language. Now one can write C in Fortran.

gah4

unread,
Jul 2, 2021, 1:21:55 AM7/2/21
to
On Thursday, July 1, 2021 at 9:47:52 PM UTC-7, Phillip Helbig (undress to reply) wrote:

(snip)
> Someone once quipped that a Fortran programmer can write Fortran in any
> language. Now one can write C in Fortran.

For some years, I suspect my C code looked a lot like Fortran.

And more recently, my Java looks like C.
Especially since they added System.out.format(), which works much
like C's printf.

and my VHDL looks a lot like Verilog.

Steve Lionel

unread,
Jul 2, 2021, 9:26:01 AM7/2/21
to
On 7/1/2021 6:20 PM, gah4 wrote:
> Fortran has the MERGE function, which mostly works in place of a conditional operator.
> MERGE does have the disadvantage in that, at least potentially, both are evaluated.
>
> C's operator guarantees not to evaluate the wrong one, in a similar way to
> short-circuit logical operators not evaluating the right operand unnecessarily.
> (Both are especially convenient when there might be out-of-bounds
> subscripts for array references.)
>
> I wonder if they will now continue to add operators to replace functions,
> such as the bitwise logical operations and MOD function.

This is not simply a replacement of MERGE (which, as noted, may evaluate
both true and false operands). In particular, you can use the new syntax
to conditionally pass arguments, including the ability to conditionally
omit an argument - try doing THAT with MERGE!

--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org

gah4

unread,
Jul 2, 2021, 9:46:32 AM7/2/21
to
On Friday, July 2, 2021 at 6:26:01 AM UTC-7, Steve Lionel wrote:
> On 7/1/2021 6:20 PM, gah4 wrote:
> > Fortran has the MERGE function, which mostly works in place of a conditional operator.
> > MERGE does have the disadvantage in that, at least potentially, both are evaluated.

> > C's operator guarantees not to evaluate the wrong one, in a similar way to
> > short-circuit logical operators not evaluating the right operand unnecessarily.
> > (Both are especially convenient when there might be out-of-bounds
> > subscripts for array references.)

> > I wonder if they will now continue to add operators to replace functions,
> > such as the bitwise logical operations and MOD function.

> This is not simply a replacement of MERGE (which, as noted, may evaluate
> both true and false operands). In particular, you can use the new syntax
> to conditionally pass arguments, including the ability to conditionally
> omit an argument - try doing THAT with MERGE!

So you put no operand in, and that passes through as an optional argument
that isn't there?

I am now trying to remember, if you pass an optional argument as an
actual arguement to another routine, does the optionalness pass through?

It seems that if optional arguments were added to MERGE, that would have
allowed for it. Also, MERGE could have been specified not to evaluate the
argument that doesn't need to be evaluated, at least in the scalar case.
(Not quite as obvious are arrays.)






Steve Lionel

unread,
Jul 2, 2021, 7:40:09 PM7/2/21
to
On 7/2/2021 9:46 AM, gah4 wrote:
> So you put no operand in, and that passes through as an optional argument
> that isn't there?
>
> I am now trying to remember, if you pass an optional argument as an
> actual arguement to another routine, does the optionalness pass through?

You can read the specification at
https://j3-fortran.org/doc/year/21/21-157r2.txt

https://j3-fortran.org/doc/year/20/20-142.txt is also worthwhile reading.

A new syntax term, .NIL., is added to signify an absent argument. And,
yes, optionalness passes through (that's already the case.)

gah4

unread,
Jul 2, 2021, 10:11:54 PM7/2/21
to
On Friday, July 2, 2021 at 4:40:09 PM UTC-7, Steve Lionel wrote:

(snip)
> You can read the specification at
> https://j3-fortran.org/doc/year/21/21-157r2.txt
>
> https://j3-fortran.org/doc/year/20/20-142.txt is also worthwhile reading.
>
> A new syntax term, .NIL., is added to signify an absent argument. And,
> yes, optionalness passes through (that's already the case.)

Pretty neat.

I hadn't thought about the case of conditional arguments being
variables that can be changed. That doesn't occur in call-by-value
C or Java.

And I am glad that they didn't use the syntax that VHDL has, which
I once thought came from Ada, but it seems not:

(then expression) WHEN (condition) ELSE (else expression)

I have no idea where they came up with that. Verilog has the C form.

FortranFan

unread,
Jul 3, 2021, 12:31:35 AM7/3/21
to
On Friday, July 2, 2021 at 7:40:09 PM UTC-4, Steve Lionel wrote:

> ..
> You can read the specification at
> https://j3-fortran.org/doc/year/21/21-157r2.txt
>
> https://j3-fortran.org/doc/year/20/20-142.txt is also worthwhile reading.
>
> A new syntax term, .NIL., is added to signify an absent argument. And,
> yes, optionalness passes through (that's already the case.)
> ..

Kudos to the leads on the committee, particularly the author of above papers. This feature encountered a fair bit of scrutiny and considerable differences in opinion. The resulting design has turned out brilliant, from what I can gage at this point.

it will be an excellent option in the language for many Fortranners who need to write compact statements e.g., in "glue" code between libraries and/or need to consume certain libraries (e.g., 3rd party) with *pesky* APIs that make heavy use of optional arguments, etc.

JCampbell

unread,
Jul 3, 2021, 8:03:32 AM7/3/21
to
I am puzzled with the introduction of a new special character "?".
It looks to be a strange choice. Looks to be unrelated to it's general meaning, which could introduce added confusion.
Does it have history ?
What is the problem in using ":" as the seperator or some other symbol.

Phillip Helbig (undress to reply)

unread,
Jul 3, 2021, 8:18:13 AM7/3/21
to
In article <aa0c4808-18d6-4945...@googlegroups.com>,
JCampbell <campbel...@gmail.com> writes:

> On Friday, July 2, 2021 at 1:58:24 AM UTC+10, Beliavsky wrote:
> > See https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code example
> >
> > y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )
> >
> > equivalent to
> >
> > if (i>=1 .And. i<=Size(a)) then
> > y = a(i)
> > else
> > y = -Huge(y)
> > end if
> >
> > I think it will be a nice addition to the language, inspired by the ternary operator of C.
> I am puzzled with the introduction of a new special character "?".

Why?

> It looks to be a strange choice. Looks to be unrelated to it's general
> meaning, which could introduce added confusion.

Seems like a logical choice.

> Does it have history ?

I think it is used in C.

> What is the problem in using ":" as the seperator or some other symbol.

Think about it. It's a question, hence the question mark. It is
followed by the yes and no answers, separated by a colon.

gah4

unread,
Jul 3, 2021, 1:10:50 PM7/3/21
to
On Saturday, July 3, 2021 at 5:18:13 AM UTC-7, Phillip Helbig (undress to reply) wrote:
> In article <aa0c4808-18d6-4945...@googlegroups.com>,
> JCampbell <campbel...@gmail.com> writes:

(snip)
> > Does it have history ?

> I think it is used in C.

and C++ and Java and verilog.

Clive Page

unread,
Jul 3, 2021, 5:35:01 PM7/3/21
to
You beat me to it. I was also going to point out that the merge instrinsic does the same thing.

--
Clive Page

Steve Lionel

unread,
Jul 3, 2021, 8:12:53 PM7/3/21
to
On 7/3/2021 8:18 AM, Phillip Helbig (undress to reply) wrote:

>>> I think it will be a nice addition to the language, inspired by the ternary operator of C.
>> I am puzzled with the introduction of a new special character "?".
>
> Why?
>
>> It looks to be a strange choice. Looks to be unrelated to it's general
>> meaning, which could introduce added confusion.

I suggest you take a look at https://en.wikipedia.org/wiki/%3F:

Gary Scott

unread,
Jul 3, 2021, 9:42:00 PM7/3/21
to
On 7/3/2021 7:12 PM, Steve Lionel wrote:
> On 7/3/2021 8:18 AM, Phillip Helbig (undress to reply) wrote:
>
>>>> I think it will be a nice addition to the language, inspired by the
>>>> ternary operator of C.
>>> I am puzzled with the introduction of a new special character "?".
>>
>> Why?
>>
>>> It looks to be a strange choice. Looks to be unrelated to it's general
>>> meaning, which could introduce added confusion.
>
> I suggest you take a look at https://en.wikipedia.org/wiki/%3F:
>
"
Mathematics and formal logic
In mathematics, "?" commonly denotes Minkowski's question mark function.
In equations, it can mean "questioned" as opposed to "defined".

U+225F ≟ QUESTIONED EQUAL TO
U+2A7B ⩻ LESS-THAN WITH QUESTION MARK ABOVE
U+2A7C ⩼ GREATER-THAN WITH QUESTION MARK ABOVE
In linear logic, the question mark denotes one of the exponential
modalities that control weakening and contraction."

The only really applicable portion is quoted above. Way too obscure in
my opinion.

Thomas Koenig

unread,
Jul 4, 2021, 3:24:13 AM7/4/21
to
gah4 <ga...@u.washington.edu> schrieb:

> Fortran has the MERGE function, which mostly works in place of a conditional operator.
> MERGE does have the disadvantage in that, at least potentially, both are evaluated.

MERGE also only works on arrays, so this really is new functionality,
plus... optional arguments with MERGE sounds, let's say, challenging.

> I wonder if they will now continue to add operators to replace functions,
> such as the bitwise logical operations and MOD function.

The functionality is sufficiently different so this addition makes
sense. The others you suggest probably

jfh

unread,
Jul 4, 2021, 4:01:25 AM7/4/21
to
On Sunday, July 4, 2021 at 7:24:13 PM UTC+12, Thomas Koenig wrote:
> gah4 <ga...@u.washington.edu> schrieb:
> > Fortran has the MERGE function, which mostly works in place of a conditional operator.
> > MERGE does have the disadvantage in that, at least potentially, both are evaluated.
> MERGE also only works on arrays, so this really is new functionality,

MERGE does not work only on arrays. I have been using it on scalars for years. It is elemental. The only problem is that the f90 standard 13.8.6 (and some later standards) called it an array construction function, which may have misled people for 30 years.

Ev. Drikos

unread,
Jul 4, 2021, 9:26:46 AM7/4/21
to
On 03/07/2021 02:40, Steve Lionel wrote:
> On 7/2/2021 9:46 AM, gah4 wrote:
>>...
> You can read the specification at
> https://j3-fortran.org/doc/year/21/21-157r2.txt

Hello,

I'm wondering whether the syntax definition is final, as
the equivalent syntax rule in C looks a little simpler:

conditional-expression: logical-OR-expression |
logical-OR-expression ? expression : conditional-expression


Admittedly, I haven't read the supported functionality in Fortran
but I guess it will be ie similar to that in C.


Regards,
Ev. Drikos

Jos Bergervoet

unread,
Jul 4, 2021, 12:58:04 PM7/4/21
to
Algol68 used the same symbol for else and then, which I also
found a bit unclear in those days.. But 'elif' was different:

IF somefact THEN a ELIF someotherfact THEN b ELSE c FI

is the same as

( somefact | a |: someotherfact | b | c )


--
Jos

Steve Lionel

unread,
Jul 4, 2021, 4:04:54 PM7/4/21
to
On 7/4/2021 9:26 AM, Ev. Drikos wrote:
> I'm wondering whether the syntax definition is final, as
> the equivalent syntax rule in C looks a little simpler

The syntax is as it is to avoid a possible ambiguity. It also provides
the optional argument feature. Certainly, the C syntax is known and was
considered. The original proposals were more complicated.

Thomas Koenig

unread,
Jul 5, 2021, 3:01:02 PM7/5/21
to
Steve Lionel <st...@seesignature.invalid> schrieb:

> The syntax is as it is to avoid a possible ambiguity. It also provides
> the optional argument feature. Certainly, the C syntax is known and was
> considered. The original proposals were more complicated.

Thanks for adding this! This will really make code more readable.

I see a lot of

b = (present (a) ? a : 42)

lines coming up :-)

Ron Shepard

unread,
Jul 6, 2021, 2:42:01 AM7/6/21
to
Instead of

b = 42; if(present(a)) b = a

That would not be much of an argument for adding it to the language. I
think the real advantage (if I understand it correctly) is that the
result is modifiable and can be used in a calling sequence as an actual
argument that associates with an intent(out) dummy argument. And since
it is modifiable, I'm wondering if it can be used on the left hand side
of an equals sign?

(present(a) ? a : b) = <expression>

rather than

if ( present(a) ) then
a = <expression>
else
b = <expression>
endif

$.02 -Ron Shepard


Steve Lionel

unread,
Jul 6, 2021, 10:44:04 AM7/6/21
to
On 7/6/2021 2:41 AM, Ron Shepard wrote:
> And since it is modifiable, I'm wondering if it can be used on the left
> hand side of an equals sign?

No.The syntax added is for a conditional expression, which can be a
"primary" in an expression (see
https://stevelionel.com/drfortran/2021/04/03/doctor-fortran-in-order-order/),
or as a conditional actual argument in a procedure reference.

There is nothing I can think of that would block adding this third usage
in the future, but it was not included in the design.

Ev. Drikos

unread,
Jul 6, 2021, 11:11:53 AM7/6/21
to
On 04/07/2021 23:04, Steve Lionel wrote:
> On 7/4/2021 9:26 AM, Ev. Drikos wrote:
>> I'm wondering whether the syntax definition is final, as
>> the equivalent syntax rule in C looks a little simpler
>
> The syntax is as it is to avoid a possible ambiguity. It also provides
> the optional argument feature. Certainly, the C syntax is known and was
> considered...
>

OK, I'm not aware ie for possible compiler specific extensions, if any.
Just tried a very simple rule without parentheses and saw no conflicts
in a LALR based parser but I'm not sure if such rule would break
statement classification that is clearly affected.

BTW, Fortran has the most accurate BNF syntax rules I've seen in a draft.

Thank you,
Ev. Drikos

gah4

unread,
Jul 6, 2021, 3:48:49 PM7/6/21
to
On Monday, July 5, 2021 at 11:42:01 PM UTC-7, Ron Shepard wrote:

(snip)

> Instead of
>
> b = 42; if(present(a)) b = a
>
> That would not be much of an argument for adding it to the language. I
> think the real advantage (if I understand it correctly) is that the
> result is modifiable and can be used in a calling sequence as an actual
> argument that associates with an intent(out) dummy argument. And since
> it is modifiable, I'm wondering if it can be used on the left hand side
> of an equals sign?
>
> (present(a) ? a : b) = <expression>

You can't do that in C, but in the case of pointers, which they would be
for modifiable arguments in C:

int *a, *b
...
*(a?a:b) = 3;

The operand of the * (pointer dereference) operator can be any pointer
expression.

And for those writing for the IOCCC (International Obfuscated
C coding contest):

0[a?a:b]=3;

As for what you can put on the left side of an assignment,
PL/I has pseudo-variables, for example:

imag(z) = 3;

to change the imaginary part of a complex variable, and even:

dcl z complex float bin(53);
z=0;
do imag(z) = 1 to 100;
put skip list(z, z**z);
end;

in which case imag() is both pseudo-variable and function.
(And a complex variable as a DO variable.)



gah4

unread,
Jul 6, 2021, 4:00:13 PM7/6/21
to
On Sunday, July 4, 2021 at 1:04:54 PM UTC-7, Steve Lionel wrote:
> On 7/4/2021 9:26 AM, Ev. Drikos wrote:
> > I'm wondering whether the syntax definition is final, as
> > the equivalent syntax rule in C looks a little simpler

> The syntax is as it is to avoid a possible ambiguity. It also provides
> the optional argument feature. Certainly, the C syntax is known and was
> considered. The original proposals were more complicated.

The syntax for nesting them looked more complicated than I thought
it needed to be. In C, they naturally nest, as a conditional expression
can be used in any of the expressions of another one.

But also, the : is not optional in C, which does complicate nesting
in the Fortran case.

x = i ? a : j ? b : c;

x = i ? j ? a : b : k ? c : d;

I suspect you need parentheses to make:

x = (i ? j : k) ? a : b;

work right.

Ev. Drikos

unread,
Jul 7, 2021, 1:15:25 AM7/7/21
to
On 06/07/2021 23:00, gah4 wrote:
> But also, the : is not optional in C, which does complicate nesting
> in the Fortran case.

Obviously, in Fortran it ended up more complex for some reason, whereas
an optional ':' for arguments would complicate (slightly) the syntax
as demonstrated in the 2nd BNF rule below. But the special token .NIL.
is apparently more powerful.

What really matters is that Fortran supports now conditional
expressions, the syntax details doesn't seem to be very important.


Regards,
Ev. Drikos

--------------------------------------------------------------------

<actual-arg> ::=
<expr>
| <alt-return-spec>
| *
| <vms-argument>
| <conditional-argument>

<conditional-argument> ::=
<expr> ? <expr> -: { : }

<expr> ::=
<expr> ? <expr> : <expr>
| <expr> <defined-binary-op> <expr>
| <expr> <equiv-op> <expr>
| <expr> <or-op> <expr>
| <expr> <and-op> <expr>
| <not-op> <expr>
| <expr> <rel-op> <expr> ~: <rel-op>
| <expr> <concat-op> <expr>
| <expr> <add-op> <expr>
| <expr> <mult-op> <expr>
| <expr> <power-op> <expr> -: { <power-op> }
| <unary-op> <expr> -: { <power-op> | <mult-op> }
| <primary>
| <defined-unary-op> <primary>

pehache

unread,
Jul 7, 2021, 5:36:13 AM7/7/21
to
Le 01/07/2021 à 17:58, Beliavsky a écrit :
> See https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code example
>
> y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )
>
> equivalent to
>
> if (i>=1 .And. i<=Size(a)) then
> y = a(i)
> else
> y = -Huge(y)
> end if
>
> I think it will be a nice addition to the language, inspired by the ternary operator of C.
>

Apart from being more cryptic, I can't see any advantage over the
if/then/else construct

--
"...sois ouvert aux idées des autres pour peu qu'elles aillent dans le
même sens que les tiennes.", ST sur fr.bio.medecine

Gary Scott

unread,
Jul 7, 2021, 8:08:30 AM7/7/21
to
On 7/7/2021 4:36 AM, pehache wrote:
> Le 01/07/2021 à 17:58, Beliavsky a écrit :
>> See
>> https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky
>> referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code
>> example
>>
>>    y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )
>>
>> equivalent to
>>
>> if (i>=1 .And. i<=Size(a)) then
>>     y = a(i)
>> else
>>     y = -Huge(y)
>> end if
>>
>> I think it will be a nice addition to the language, inspired by the
>> ternary operator of C.
>>
>
> Apart from being more cryptic, I can't see any advantage over the
> if/then/else construct
>
Yes!

FortranFan

unread,
Jul 7, 2021, 8:41:19 AM7/7/21
to
On Wednesday, July 7, 2021 at 5:36:13 AM UTC-4, pehache wrote:

> ..
> Apart from being more cryptic, I can't see any advantage over the
> if/then/else construct
> ..

Re: ".. I can't see any advantage over the if/then/else construct ..," that is an incorrect assessment of this new feature in Fortran 202X.

As noted upthread, there can be considerable advantage with this feature when it comes to reference to procedures with optional arguments and the advantage scales rapidly with the number of optional arguments.

And to reiterate, the additional advantage is with those who seek compact code.

dpb

unread,
Jul 7, 2021, 10:09:50 AM7/7/21
to
I grant the first is powerful and makes it worth it for that reason.

As for the second, I suppose one eventually gets familiar-enough with
the idiom it isn't so obfuscating, but personally I still find it more
confusing than helpful in C albeit I'll be first to admit have written
only as much C as was forced into over the last 40 years.

If one likes terse, that's one's privilege and I'm first to agree the
language shouldn't go out of its way to prevent the user from coding as
suits their style/taste.

But, does the ternary form do anything to aid the compiler in producing
any better/faster/more optimized code than the equivalent if...end
construct?

Either/both just turn into conditional branch/jump don't they? Same as
a computed GOTO vs a CASE structure; the point is more for the human
than the computer/compiler so there's advantages to clarity as well.

$0.02, imo, ymmv, etc., etc., etc., ...

--

Robin Vowels

unread,
Jul 8, 2021, 12:34:47 AM7/8/21
to
On Friday, July 2, 2021 at 1:58:24 AM UTC+10, Beliavsky wrote:
.
bizarre syntax, cryptic, and archaic.
It seems to be an attempt to revive something from Algol 60, viz,
y = if a>b then x else z;
which is less bizarre.
.

gah4

unread,
Jul 8, 2021, 4:26:04 AM7/8/21
to
On Wednesday, July 7, 2021 at 7:09:50 AM UTC-7, dpb wrote:

(snip)

> I grant the first is powerful and makes it worth it for that reason.

j=0
if(a) j=ior(j,1)
if(b) j=ior(j,2)
if(c) j=ior(j,4)
select case(j)
case (0)
call sub(,,)
case (1)
call sub(a,,)
case (2)
call sub(,b,)
case (3)
call sub(a,b,)
case (4)
call sub(,,c)
case (5)
call sub(a,,c)
case (6)
call sub(,b,c)
case (7)
call sub(a,b,c)
end select

Yes, not so terse.

Other uses, as noted above, can also be done with MERGE.

> As for the second, I suppose one eventually gets familiar-enough with
> the idiom it isn't so obfuscating, but personally I still find it more
> confusing than helpful in C albeit I'll be first to admit have written
> only as much C as was forced into over the last 40 years.

> If one likes terse, that's one's privilege and I'm first to agree the
> language shouldn't go out of its way to prevent the user from coding as
> suits their style/taste.

if(l) then
print *,a,x,c
else
print *,a,y,c
endif

Or use a temporary variable:

t=y
if(l) t=x
print *,a,t,c

or MERGE

print *,a,MERGE(x,y,l),c

or the new operator

print *,a, l?x:y, c

However, MERGE, like most function calls, evaluates its arguments
before executing the function. (That is, except for inquiry functions.)

print *,a,MERGE(x(i), y(j),l), c

evaluates array references which might have out of bounds subscripts.
Defining MERGE not to evaluate an argument when not necessary,
even though no other function has that requirement, could have fixed this.


> But, does the ternary form do anything to aid the compiler in producing
> any better/faster/more optimized code than the equivalent if...end
> construct?

Since it guarantees not to evaluate the unselected operand,
it could be faster than MERGE. I think it looks a lot better than
lots of temporary variables, just for storing selected values.
And a big advantage when you can't evaluate the other operand.


> Either/both just turn into conditional branch/jump don't they? Same as
> a computed GOTO vs a CASE structure; the point is more for the human
> than the computer/compiler so there's advantages to clarity as well.

Many processors now have a conditional load instruction, which helps
avoid the uncertainty of branch destinations. But that only works
when you can actually evaluate all the operands.



pehache

unread,
Jul 8, 2021, 7:42:02 AM7/8/21
to
Le 07/07/2021 à 14:41, FortranFan a écrit :
> On Wednesday, July 7, 2021 at 5:36:13 AM UTC-4, pehache wrote:
>
>> ..
>> Apart from being more cryptic, I can't see any advantage over the
>> if/then/else construct
>> ..
>
> Re: ".. I can't see any advantage over the if/then/else construct ..," that is an incorrect assessment of this new feature in Fortran 202X.
>
> As noted upthread, there can be considerable advantage with this feature when it comes to reference to procedures with optional arguments and the advantage scales rapidly with the number of optional arguments.

I don't really get that... An exemple maybe ?

Actually the advantage is that the result can be used directly within an
expression, but there was no need to chose a cryptic syntax. As stated
in another post, something like
y = if (condition) then ; <expression> ; else ; expression ; endif

would have do

>
> And to reiterate, the additional advantage is with those who seek compact code.
>

Fortran is not for compact code.

Thomas Koenig

unread,
Jul 8, 2021, 10:22:59 AM7/8/21
to
pehache <peha...@gmail.com> schrieb:

>
> Actually the advantage is that the result can be used directly within an
> expression, but there was no need to chose a cryptic syntax. As stated
> in another post, something like
> y = if (condition) then ; <expression> ; else ; expression ; endif
>
> would have do

There was one certainty: Whatever syntax was chosen, some people
would object :-)

The current one is rather similar to C, which means that people who
know the feature from other programming languages will recognize it.

Certainly good enough for me.

pehache

unread,
Jul 8, 2021, 1:25:57 PM7/8/21
to
I prefer new syntaxes that are consistent with existing Fortran rather
than new syntaxes that are consistent with C.

Even without any knowledge of Fortan, any developer is able to figure
out what does mean :
y = if (i>=1.and.i<=Size(a)) then ; a(i) ; else ; -Huge(y) ; endif

While only C* developers can figure out what does means :
y = ( i>=1.and.i<=Size(a) ? a(i) : -Huge(y) )

gah4

unread,
Jul 8, 2021, 9:38:25 PM7/8/21
to
On Thursday, July 8, 2021 at 4:42:02 AM UTC-7, pehache wrote:

(snip, someone wrote)
> > As noted upthread, there can be considerable advantage with this feature when it
> > comes to reference to procedures with optional arguments and the advantage
> > scales rapidly with the number of optional arguments.

> I don't really get that... An exemple maybe ?

I wrote this above, calling a subroutine with three optional arguments, in
all combinations.

Ron Shepard

unread,
Jul 9, 2021, 3:13:24 AM7/9/21
to
I would say this is confusing at best. The "a", "b", and "c" variables
are logical, and used to set j, which is only used to select the call.
But sub() is always called with .true. present arguments and .false'
nonpresent arguments (assuming that syntax even works), so why not just have

call sub(a,b,c)

to cover all the cases? The arguments have .true. or .false. values,
which the subprogram can test in the straightforward way. No need for
optional attributes, where the present dummy arguments are always .true.
and the nonpresent arguments are always .false.

On the other hand, if "a", "b", and "c" are themselves optional
arguments (of any type), then

call sub(a,b,c)

passes their present() status down to sub() in the straightforward way.
This is a very useful feature of the language (since f90).

An example of the conditional expression is

call sub( (<expression> ? a : b) )

which is equivalent to

if ( expression ) then
call sub(a)
else
call sub(b)
endif

Now consider a subroutine with more than one such argument. Each
argument would double the number of possible if-then-else branches
(O(2^N) coding effort) required to select the correct calling sequence,
but it can be done with a single call using the multiple conditional
expressions (O(N) coding effort). Further, this cannot be done with
MERGE, because the result of MERGE is an modifiable expression. That
means it can be associated with intent(out) and intent(inout) dummy
arguments, and the updated values are passed back to the calling program
correctly through the argument association.

This could also be achieved with pointers, conditionally assigning each
pointer actual argument. That approach also requires O(N) rather than
O(2^N) coding effort. However that would require that the possible
arguments all be targets, which suppresses optimization in the same way
that C, C++, etc. languages have suppressed optimization due to wild
pointers.

In my opinion, the fact that the result is modifiable is the real useful
feature of the conditional expression semantics. When used to replace
MERGE or IF-THEN-ENDIF, it is mostly, apart from the short-circuit
feature, just redundant eye candy.

$.02 -Ron Shepard

gah4

unread,
Jul 9, 2021, 3:41:48 AM7/9/21
to
On Friday, July 9, 2021 at 12:13:24 AM UTC-7, Ron Shepard wrote:

(snip of example. See above if you forgot it.)

> I would say this is confusing at best. The "a", "b", and "c" variables
> are logical, and used to set j, which is only used to select the call.
> But sub() is always called with .true. present arguments and .false'
> nonpresent arguments (assuming that syntax even works), so why not just have

> call sub(a,b,c)

Sorry, yes, I was not very original in my variable name choice.
Consider x, y, and z as the arguments instead.

(snip)

> An example of the conditional expression is

> call sub( (<expression> ? a : b) )

> which is equivalent to

> if ( expression ) then
> call sub(a)
> else
> call sub(b)
> endif

> Now consider a subroutine with more than one such argument. Each
> argument would double the number of possible if-then-else branches
> (O(2^N) coding effort) required to select the correct calling sequence,
> but it can be done with a single call using the multiple conditional
> expressions (O(N) coding effort). Further, this cannot be done with
> MERGE, because the result of MERGE is an modifiable expression. That
> means it can be associated with intent(out) and intent(inout) dummy
> arguments, and the updated values are passed back to the calling program
> correctly through the argument association.

I believe that MERGE cannot be used with intent(out) or intent(inout)
arguments, but I haven't thought about this recently.

Ev. Drikos

unread,
Jul 9, 2021, 3:43:47 AM7/9/21
to
On 08/07/2021 14:41, pehache wrote:
>
> I don't really get that... An exemple maybe ?
> ...
>
> Fortran is not for compact code.
>

Here is a C function call. The last two arguments I've added use the
ternary operator. Without it the code fragment would be longer. But
when one needs to debug, this cryptic operator makes the task harder.

Some times I temporarily replace a ternary op in an assignment with a
classic If-Else statement to see what is really called.

Regards,
Ev. Drikos

---------------------------------------------------------------------

tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
gfc_expr_is_variable (expr2)
|| scalar_to_array
|| expr2->expr_type == EXPR_ARRAY,
!(l_is_temp || init_flag) && dealloc,
expr1->symtree->n.sym->attr.codimension,
gfc_bt_struct (expr2->ts.type) &&
(gfc_expr_is_variable (expr2)
|| scalar_to_array
|| expr2->expr_type == EXPR_ARRAY
|| expr2->expr_type == EXPR_STRUCTURE)? expr1: NULL,
scalar_to_array && dealloc? NULL: expr2);

Ev. Drikos

unread,
Jul 9, 2021, 4:33:45 AM7/9/21
to
On 07/07/2021 08:15, Ev. Drikos wrote:
> <conditional-argument> ::=
>            <expr> ? <expr> -: { : }

Just for the record, Follow Restrictions aren't required in this rule,
whereas, the ternary operator is Right-Associative. So, I post again
along with an example (without questioning the recommended syntax).

Ev. Drikos

------------------
program example
v1 = f( x ? arg ); ! 1. Optional argument
v2 = x ? a : y ? b : z ! 2. Right associative ternary
operator as in C
v3 = f((x ? a : y ? b : z ) ? arg) ! 3. Parentheses required when 1
and 2 are nested
end
------------------

<actual-arg> ::=
<expr>
| <alt-return-spec>
| *
| <vms-argument>
| <conditional-argument>

<conditional-argument> ::=
<expr> ? <expr>

<expr> ::=
<expr> ? <expr> : <expr> -: { ? }

Ron Shepard

unread,
Jul 9, 2021, 4:01:27 PM7/9/21
to
On 7/9/21 2:41 AM, gah4 wrote:
>> Now consider a subroutine with more than one such argument. Each
>> argument would double the number of possible if-then-else branches
>> (O(2^N) coding effort) required to select the correct calling sequence,
>> but it can be done with a single call using the multiple conditional
>> expressions (O(N) coding effort). Further, this cannot be done with
>> MERGE, because the result of MERGE is an modifiable expression. That
>> means it can be associated with intent(out) and intent(inout) dummy
>> arguments, and the updated values are passed back to the calling program
>> correctly through the argument association.
> I believe that MERGE cannot be used with intent(out) or intent(inout)
> arguments, but I haven't thought about this recently.

Yes, that was a typo in that sentence. I meant "unmodifiable" for MERGE,
in contrast to "modifiable" for the conditional expression.

$.02 -Ron Shepard

gah4

unread,
Jul 9, 2021, 9:30:51 PM7/9/21
to
On Friday, July 9, 2021 at 1:01:27 PM UTC-7, Ron Shepard wrote:

(snip)
> > I believe that MERGE cannot be used with intent(out) or intent(inout)
> > arguments, but I haven't thought about this recently.

> Yes, that was a typo in that sentence. I meant "unmodifiable" for MERGE,
> in contrast to "modifiable" for the conditional expression.

That is what I suspected, but wanted to make sure, so no-one else
gets confused.

I think the ability not to evaluate both arguments could have been added to
merge. But modifiable arguments would have been a less obvious addition.

rbader

unread,
Jul 10, 2021, 2:18:35 PM7/10/21
to
Steve Lionel schrieb am Dienstag, 6. Juli 2021 um 16:44:04 UTC+2:
> On 7/6/2021 2:41 AM, Ron Shepard wrote:
> > And since it is modifiable, I'm wondering if it can be used on the left
> > hand side of an equals sign?
> No.The syntax added is for a conditional expression, which can be a
> "primary" in an expression (see
> https://stevelionel.com/drfortran/2021/04/03/doctor-fortran-in-order-order/),
> or as a conditional actual argument in a procedure reference.
>
> There is nothing I can think of that would block adding this third usage
> in the future, but it was not included in the design.

It might be quite easy to add the little bits that would permit

ASSOCIATE ( a => <conditional expr> )
a = ...
END ASSOCIATE

since the relationship to argument association is so close.

Cheers
Reinhold

JCampbell

unread,
Jul 11, 2021, 12:19:53 AM7/11/21
to
Would the limited "if then else" structure of the conditional expression provide opportunity for improved optimisation ?

gah4

unread,
Jul 11, 2021, 3:26:42 PM7/11/21
to
On Saturday, July 10, 2021 at 9:19:53 PM UTC-7, JCampbell wrote:

(snip)
> Would the limited "if then else" structure of the conditional expression provide opportunity for improved optimisation ?

As well as I know, MERGE is allowed to optimize, only evaluating one argument,
but isn't required to do that. The new operator requires it.

Ron Shepard

unread,
Jul 12, 2021, 12:26:05 PM7/12/21
to
That hypothetical situation works the other way too. MERGE is allowed to
optimize by evaluating its arguments early (reusing register values,
minimizing memory references, reusing allocated temporary arrays, etc.),
and the new operator forbids that optimization, requiring the short
circuit semantics instead.

$.02 -Ron Shepard

gah4

unread,
Jul 12, 2021, 4:43:32 PM7/12/21
to
On Monday, July 12, 2021 at 9:26:05 AM UTC-7, Ron Shepard wrote:

(snip, I wrote)

> > As well as I know, MERGE is allowed to optimize, only evaluating one argument,
> > but isn't required to do that. The new operator requires it.

> That hypothetical situation works the other way too. MERGE is allowed to
> optimize by evaluating its arguments early (reusing register values,
> minimizing memory references, reusing allocated temporary arrays, etc.),
> and the new operator forbids that optimization, requiring the short
> circuit semantics instead.

I suppose so. Well, it is only a problem with side effects.

As far as I know, the biggest side effect is array references.
I have a program from the Fortran 66 days with:

970 IF ((B.LE.0.OR.IB(B).NE.LL+1)) GO TO 1010

As long as you don't do bounds checking, it works fine.
I suspect that in the logic, B can be zero, or maybe slightly
negative, but not so far to get outside the program's memory
space.

But there are more ways to have side effects in C.

printf("%d", s? a[i++] : b[j++]);

depending on which one is selected, i or j is incremented,
but also the array reference has to be in bounds.

But the Fortran rules on side-effects are different from C, and I suspect
still apply in this case.




Lynn McGuire

unread,
Jul 12, 2021, 4:50:58 PM7/12/21
to
We agree on something. I have never used this syntax in C as I dislike it.

Lynn

gah4

unread,
Jul 12, 2021, 7:24:45 PM7/12/21
to
On Monday, July 12, 2021 at 1:50:58 PM UTC-7, Lynn McGuire wrote:

(snip, someone wrote)

> >> I think it will be a nice addition to the language, inspired by the ternary operator of C.

> We agree on something. I have never used this syntax in C as I dislike it.

Fun with the C preprocessor:

#define MERGE(x, y, z) ((z) ? (x) : (y))

There is a long history of people using the C preprocessor to
avoid parts of C that they don't like. Rumors of Pascal users:

#define BEGIN {
#define END {



Thomas Koenig

unread,
Jul 13, 2021, 1:09:42 AM7/13/21
to
gah4 <ga...@u.washington.edu> schrieb:

> There is a long history of people using the C preprocessor to
> avoid parts of C that they don't like. Rumors of Pascal users:
>
>#define BEGIN {
>#define END {

I assume you mean

#define END }

:-)

And it fact that the original Bourne shell was written in a style
like that. Stephen Bourne was rather unique in that he was a
fan of Algol 68, which is why the Unix shell has some syntax
details inspired by that language.

Phillip Helbig---undress to reply

unread,
Jul 13, 2021, 3:33:05 AM7/13/21
to
In article <scj76j$b87$1...@newsreader4.netcologne.de>, Thomas Koenig
A Fortran programmer can write Fortran in any language.

Lynn McGuire

unread,
Jul 27, 2021, 4:01:27 PM7/27/21
to
Heh. I resemble that.

Lynn

Dominik Gronkiewicz

unread,
Sep 2, 2021, 6:41:35 AM9/2/21
to
czwartek, 1 lipca 2021 o 17:58:24 UTC+2 Beliavsky napisał(a):
> See https://fortran-lang.discourse.group/t/poll-fortran-202x-conditional-expressions-syntax/1425/80?u=beliavsky referencing https://j3-fortran.org/doc/year/21/21-157r2.txt with code example
>
> y = ( i>=1 .And. i<=Size(a) ? a(i) : -Huge(y) )
>
> equivalent to
>
> if (i>=1 .And. i<=Size(a)) then
> y = a(i)
> else
> y = -Huge(y)
> end if
>
> I think it will be a nice addition to the language, inspired by the ternary operator of C.

It is a bit disappointing that instead of borrowing syntax from modern languages (such as Python), it is taken from outdated languages (C). Sadly, while the functionality is a step forward, and I'm very excited to use it, syntactically it's a mess, as it comes from a totally unrelated language. Was there any motivation of such a choice over more modern syntax, such as this?

y = a(i) if i>=1 .and. i<=Size(a) else -Huge(y)

Dominik

spectrum

unread,
Sep 2, 2021, 8:58:51 AM9/2/21
to
Dominik wrote:
> Was there any motivation of such a choice over more modern syntax, such as this?
> y = a(i) if i>=1 .and. i<=Size(a) else -Huge(y)

I feel it is interesting (and a bit surprising) that the committee chose the C-like ternary
form, but as for the above Python form, isn't it "problematic" to use for fixed-form
source form with the (notorious) implicit rule? (because spaces are neglected), e.g.,

program main
integer, parameter :: lo = 0, hi = 5
integer :: i
real :: a, b
read *, i
a = 1.23; b = 4.56
print *, a if i >= lo .and. i < hi else b
end

$ gfortran-10 test.f
$ ./a.out !! results are meaningless, but it compiles + gives some value
-1
T

I believe it is better to introduce a new syntax only for free-form + implicit none codes
(then there is no need for such consideration for neglect of spaces etc).

FortranFan

unread,
Sep 3, 2021, 10:53:43 AM9/3/21
to
On Thursday, September 2, 2021 at 8:58:51 AM UTC-4, spectrum wrote:

> ..
> I feel it is interesting (and a bit surprising) that the committee chose the C-like ternary
> form, but as for the above Python form, isn't it "problematic" to use for fixed-form
> source form with the (notorious) implicit rule? (because spaces are neglected), e.g., ..

In essence, @spectrum is right: the committee did consider quite a few options but the need for the syntax to also work with fixed-form source filtered out most.

This is among several reasons I now feel the Fortran standard needs to have a third category of outmoded features, say RETIRED. Please see this:
https://github.com/j3-fortran/fortran_proposals/issues/225#issue-979802884

Fixed-form has been obsolescent since Fortran 95 which was nearly 25 years ago. So technically an entire generation has grown up knowing the fixed-form source is not only too limiting but it also officially recognized as outmoded.

But still no matter what, the chances of fixed-form source ever going to be deleted from the standard might very well be the definition of absolute zero. The entrenched interests and intransigence when it comes to moving beyond fixed-form source is insurmountable.

But then also, the chances of any modern Fortran features such as conditional expressions being used in fixed-form source are low enough to be statistically insignificant.

Considering all this, can everyone involved with Fortran please come to a consensus and understanding and at least retire fixed-form source so as to *not* to burden any and all current (like with conditional expressions in the case of this thread) and future features (Generics, exception handling, etc.) and specifically their syntax with the need to have backward compatibility with fixed-form source where blanks are insignificant?

Can the Fortran standard at least mark fixed-form source as RETIRED? Please.

JRR

unread,
Sep 4, 2021, 3:53:57 PM9/4/21
to
Am 03.09.21 um 16:53 schrieb FortranFan:
I greatly support that idea. There will always be compiler options that
allow compilation of such legacy codes, but all new features in my
opinion only really need to properly work with free-form.

--
Juergen Reuter
Theoretical Particle Physics
Deutsches Elektronen-Synchrotron (DESY)
Hamburg, Germany

gah4

unread,
Sep 5, 2021, 2:26:13 AM9/5/21
to
On Thursday, September 2, 2021 at 3:41:35 AM UTC-7, gro...@gmail.com wrote:

(snip)
> Was there any motivation of such a choice over more modern syntax, such as this?
>
> y = a(i) if i>=1 .and. i<=Size(a) else -Huge(y)

VHDL has

y <= a(i) when i>1 and i<=s else j;

and I hate it. Well, for one, I learned verilog first, which I like better for lots of other reasons,
but one reason I don't like that form of the operator is that it has the wrong symmetry.

I can see it with the selecting expression first, or (like in RPN languages) last,
but it seems wrong in the middle. It looks even worse when nested.

Thomas Koenig

unread,
Sep 5, 2021, 5:44:48 AM9/5/21
to
JRR <juergen...@invalid.com> schrieb:
> Am 03.09.21 um 16:53 schrieb FortranFan:
>> On Thursday, September 2, 2021 at 8:58:51 AM UTC-4, spectrum wrote:
>>
> the need to have backward compatibility with fixed-form source where
> blanks are insignificant?
>>
>> Can the Fortran standard at least mark fixed-form source as RETIRED? Please.
>>
>
> I greatly support that idea. There will always be compiler options that
> allow compilation of such legacy codes, but all new features in my
> opinion only really need to properly work with free-form.

A basic problem with marking features obsolete is that the
interaction between those features and newer ones is no longer
defined.

If all compilers will continue to support the old feature, this
creates ambiguity for the compiler writers and the users, which
is a Bad Thing (TM).

FortranFan

unread,
Sep 5, 2021, 9:09:33 PM9/5/21
to
On Sunday, September 5, 2021 at 5:44:48 AM UTC-4, Thomas Koenig wrote:

> ..
> If all compilers will continue to support the old feature, this
> creates ambiguity for the compiler writers and the users, which
> is a Bad Thing (TM).


A honest reckoning with reality is a Fortran standard does not dare to obsolesce and retire certain unsavory features from earlier revisions is a Much, Much Worse Thing (no TM) for the practitioners.

Ron Shepard

unread,
Sep 6, 2021, 5:31:59 PM9/6/21