## The new Fortran 2023 standard was adopted

At the end of 2023, another Fortran language standard, ISO/IEC 1539-1:2023, was adopted. Programming languages. Fortran (in vernacular – Fortran 2023).

The differences between the 2023 standard and the previous Fortran 2018 standard are fully described in a freely available document

The New features of Fortran 2023

which has no official status.

We will give a brief overview of the innovations.

The maximum length of the program line has been increased to 10,000 characters, the maximum length of the operator – up to one million characters. Compilers are told to follow these limits exactly, no more and no less. The goal, it says, is to make it easier for artificial intelligence to write programs.

Automatic placement of lines of variable length in memory is allowed as a result of obtaining the initial parameters of system procedures and operators (that is, the user does not need to remove the buffer by hand).

New typeof and classof attributes to create variables of the same type as others:

`integer :: i`

typeof (i) :: j

The long-awaited conditional expressions:

`value = ( a>0.0 ? a : 0.0)`

Parentheses are required, but a single expression can contain nested conditions:

`value = ( a>0.0 ? a : b > 0.0 ? b : 0.0)`

Also, the result of a conditional expression can be one or more actual parameters of the procedure, including those passed by reference or optional:

`call sub ( ( x>0? x : y>0? y : z ), ( edge>0? edge : mode==3? 1.0 : .nil.) )`

Lexeme. here conveys the absence of an actual parameter.

More advanced use of binary, octal, and hexadecimal (boz) literal constants. In the Fortran language, such literals do not have a type, being simply a record of the contents of memory cells, so their use is different from decimal numbers. In general, nowadays, when the value type can be deduced from the left part of the assignment, boz can be used for the right part.

Added useful string tokenization routines split and tokenize for efficient work with words in a string.

59 years after a similar solution was implemented in PL/I, added trigonometric functions to work with arguments in degrees (acosd to acos and so on to tand).

Added trigonometric functions for working with arguments in the interval from 0 to Pi according to the IEEE standard (from acospi to tanpi).

The selected_logical_kind function allows you to get the byte-length attribute of a logical value that will fit the specified bit size.

The parameter types of the standard system_clock routine are limited. In particular, the bit size must not be less than the default integer size.

Added new pedantic maximums and minimums functions to comply with the new IEEE standard, ISO/IEC 60559:2020 – ieee_max, ieee_max_mag, ieee_min, ieee_min_mag. Differ from the usual ones in the exact specification that is returned in the case of different NaNs, positive and negative zeros, etc.

Added integer constants logical8, logical16, logical32,

logical64, real16 to specify the sizes of the corresponding types. Note that in all reasonable compilers they are equal to 8, 16, 32, 64 and 16, respectively. Shiza mows our ranks.

Interaction with C functions has been extended with all kinds of exotic cases, such as multibyte character encoding by default.

Added the following two extremely useful innovations in format conclusion, which (at least the second one) have been waiting for almost 70 years.

The new AT output format acts like A with the trim function applied, i.e. discards extra trailing spaces:

`print "(AT,AT)", "Imperial ", "bastion"`

Imperialbastion

Finally! it is possible to control the zero stamp before the decimal point in real numbers between 0 and 1 (previously it could be either .5 or 0.5 depending on the implementation). For this, the control formats LZP, LZS, LZ (print/suppress/default) or the key parameter leading_zero=… in the open operator with the values print, suppress, processor_defined (according to some information, also in the write operator) are intended:

`print "(LZP, F0.2, 1X, LZS, F0.2)", .5, .5`

0.50.50

The syntax of the namelist operator has been extended.

Objects that are dynamically placed in memory, containing comasses, are allowed, and all this works very complexly.

The put with notify mechanism has been added, which ensures that data changes in someone else’s address space are sent with a message. For this, the syntax of the collective assignment operator has been expanded with the notify option and the notify wait operator has been added:

```
use iso_fortran_env
type(notify_type) nx[*]
me = this_image()
if (me <= 4) then
x(me)[10, notify=nx] = y
else if (me == 10) then
notify wait (nx, until_count=4)
z(1:4) = x(1:4)
end if
```

Improved handling of error states in cases where they occur only in part of parallel threads.

Added simple (simple) procedures. They differ from pure procedures in that they not only do not modify the external environment other than through formal parameters, but also do not read the external environment other than through formal parameters. Obviously useful for offloading code to GPUs and other heterogeneous architectures.

Arrays can be indexed by arrays, the dimension (number of measurements) of the array can be set dynamically, and generally a lot of debauchery in the style of the APL language:

```
A(@[3,5])
! Array element, equivalent to A(3, 5)
A(6, @[3,5], 1)
! Array element, equivalent to A(6, 3, 5, 1)
A(@V1, :, @V2)
! Rank-one array section, the rank of A being
! SIZE (V1) + 1 + SIZE (V2).
integer, dimension(3) :: lb_array = 0
real :: zz(lb_array+2:)
real, dimension(lb_array:) :: x, y
real, allocatable, dimension(:,:,:) :: x, y, z
integer :: lower(3), upper(3)
allocate(x(:upper), y(lower:upper), z(0:upper))
subroutine ex(a)
real, rank(2) :: a
! Equivalent to real :: a(:,:)
integer :: x0(10,10,10)
logical, rank(rank(x0)), allocatable :: x1
! rank 3, deferred shape
complex, rank(2), pointer :: x2
! rank 2, deferred-shape
logical, rank(rank(x0)) :: x3
! rank 3, assumed-shape
real, rank(0) :: x4
! scalar
```

The long-awaited introduction of a reduction specification to the asynchronous loop operator, previously only possible in OpenMP macros:

```
real :: a, b, x(n)
a = 0.
b = -huge(b)
do concurrent (i = 1:n) reduce(+:a) reduce(max:b)
a = a + x(i)**2
b = max(b,x(i))
end do
```

Finally, a lot of little useful features related to enums.

In general, the Fortran 2023 standard makes a positive impression, and some innovations have been expected. But at the same time, it is worrying that the ISO committee has moved away from compiler developers: the previous Fortran 2018 standard is supported by compilers only to a small extent, and the de facto standard today remains Fortran 2008. It remains to be hoped that at least the most popular in 2023 will be implemented quite quickly.