Updating assignment operators

In C++, there are many convenient updating assignment operators:

a += b,
a -= b,
a *= b,
a /= b,
a ^= b,
a %= b,
a &= b,
a |= b.

If Fortran eventually adds these operators, just curious how to implement:

a /= b,
a %= b.

This also makes me wonder why Fortran uses ! as the comment symbol in the first place.

2 Likes

There was a recent discussion about this on the J3 mailing list:

https://mailman.j3-fortran.org/pipermail/j3/2021-August/013251.html

@sblionel there suspected it wasn’t pursued because it doesn’t add new capability (i.e. syntactic sugar), and complications associated with existing /=. If you read down the thread in the mailing list, you’ll see that there is non-negligible desire/support for including a limited set of operators (+= and *=) which avoids the complication with /=.

If you want += and similar in Fortran, please post in this topic. There will be opportunity for it for F202Y.

2 Likes

Very interesting discussion.

I think that:
a /= b can be written as a *= 1/b,
a -= b can be written as a += -b,
so we only need a += b, a *= b, and a **= b.

I rarely see the use of **=, but having += and *= would be great.

PS: Both Matlab and R don’t have updating assignment operators, either. I rarely see Matlab and R users complain about this. It seems weird nobody mentioned that in the discussion.

2 Likes

Indeed, having += and *= would be great. Here is the main discussion for this addition to Fortran:

Can you and anybody else who wants this please upvote the proposal there (click on the +1 in the top issue comment)? Currently it has only 6 upvotes. If we can show that hundreds of people want this, then we might have a case. Otherwise I would say there is just not enough support for this.

And here is a prototype in LFortran of +=: Draft: Prototype implementation of the += operator (!1286) · Merge requests · lfortran / lfortran · GitLab

3 Likes

This feature really seems like a low-hanging one that will benefit Fortran users in both the short run and long run. I guess it should not be too difficult to implement. How likely is it to be added to the next Fortran standard?

I think it would not be difficult to implement in any compiler.

It will not be added to 202X. Those feature were already selected in June 2018, after that none can be added. :frowning:

However, it is still on the table for 202Y, the features of which will be down selected relatively soon.

I didn’t know the turnaround time is so long. So the feature freeze date is three years ago but 2020X is still not out? Seems too long for a niche programming language like Fortran.

A benefit of the assignment operator is avoiding typos such as

x(i,j,k) = x(i,k,j) + 1

where the LHS is not incremented by 1 because j and k are interchanged on the RHS. I have proposed adding an elemental subroutine called increment to stdlilb, so that one can write

call increment(x(i,j,k),1)

It is easy to implement:

module m
implicit none
interface increment
   module procedure increment_int,increment_real_sp
end interface increment
contains
pure elemental subroutine increment_int(i,iadd)
integer, intent(in out) :: i
integer, intent(in)     :: iadd
i = i + iadd
end subroutine increment_int
!
pure elemental subroutine increment_real_sp(x,xadd)
real, intent(in out) :: x
real, intent(in)     :: xadd
x = x + xadd
end subroutine increment_real_sp
end module m

program main
use m, only: increment
implicit none
real :: x,xvec(3)
integer :: i,ivec(3)
x = 5.2
i = 5
xvec = real([1,4,9])
call increment(x,1.3)
call increment(i,3)
call increment(xvec,10.0)
print*,x,i,xvec !    6.50000000               8   11.0000000       14.0000000       19.0000000 
call increment(xvec,real([1,2,3]))
print*,xvec ! 12.0000000       16.0000000       22.0000000
end program main

I favor adding assignment operators, but I don’t think their absence is a big problem.

I recommend you upvote this issue:

Also in addition to that, having a “rolling release” would also help to get small features like this one in.

However, I think the best way for Fortran is to actually implement features in a compiler first so that we can actually use it. And also implement translation to a subset of Fortran that compiles with other current compilers, so that one is not locked in.

One thing that I don’t know yet is how to handle these proposals: above I posted a link to LFortran where it is implemented on a branch. Obviously we probably don’t want to merge it into master. For example, what if we change our mind, etc. It could possibly be enabled with an option, but even then it requires changes to the parser, etc. If you and others have ideas how to handle theses prototypes, so that we don’t close doors for us in the future, let me know. Perhaps if there is no performance overhead, it can be enabled with an option. Otherwise it can live on a branch, or perhaps enabled with a preprocessor macro at compile time (of LFortran).