Принят новый стандарт Fortran 2023

iltto38dexzp3k6cr-twayk1ruq.jpeg

В конце 2023 года был принят очередной стандарт языка Фортран, ISO/IEC 1539–1:2023. Programming languages. Fortran (в просторечии — Fortran 2023).
Отличия стандарта 2023 года от действовавшего до него стандарта Fortran 2018 полностью описаны в свободно доступном документе The new features of Fortran 2023, не имеющем официального статуса.

Приведём короткий обзор нововведений.

Максимальная длина строки программы увеличена до 10 тысяч символов, максимальная длина одного оператора — до миллиона символов. Компиляторам предписывается в точности соблюдать эти лимиты, не более и не менее. Как утверждается, целью является облегчение написания программ искусственными интеллектами.

Разрешено автоматическое размещение в памяти строк переменной длины в результате получения выходных параметров системных процедур и операторов (т.е. пользователю не надо руками отводить буфер).

Новые атрибуты typeof и classof для создания переменных такого же типа, как другие:

integer :: i
typeof (i) :: j

Долго ожидавшиеся условные выражения:

value = ( a>0.0 ? a : 0.0)

Скобки обязательны, но одно выражение может содержать вложенные условия:

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

Также результатом условного выражения может быть один или несколько фактических параметров процедуры, в том числе передаваемых по ссылке или опускаемых необязательных:

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

Лексема .nil. здесь передаёт отсутствие фактического параметра.

Более расширенное использование двоичных, восьмеричных и шестнадцатеричных (boz) литеральных констант. В языке Фортран такие литералы не имеют типа, представляя собой просто запись содержимого ячеек памяти, поэтому их использование отличается от использования десятичных чисел. В целом, теперь, когда можно вывести тип значения по левой части присваивания, то в правой могут использоваться boz.

Добавлены полезные подпрограммы токенизации строк split и tokenize для эффективной работы со словами в строке.

Добавлены тригонометрические функции для работы с аргументами в градусах (acosd вдобавок к acos и так далее до tand).

Добавлены тригонометрические функции для работы с аргументами в интервале от 0 до Пи в соответствии со стандартом IEEE (от acospi до tanpi).

Функция selected_logical_kind позволяет получить атрибут байтовой длины логического значения, в которое уместится заданная разрядность.

Ограничены типы параметров стандартной подпрограммы system_clock. В частности, разрядность должна быть не меньше умолчательного размера integer.

Добавлены новые функции педантичных максимумов и минимумов для соответствия новому стандарту IEEE, ISO/IEC 60559:2020 — ieee_max, ieee_max_mag, ieee_min, ieee_min_mag. Отличаются от обычных точной спецификацией, что возвращается в случае различных NaN’ов, положительных и отрицательных нулей и т.п.

Добавлены целые константы logical8, logical16, logical32,
logical64, real16 для указания размеров соответствующих типов. Заметим, что во всех вменяемых компиляторах они равны 8, 16, 32, 64 и 16 соответственно. Шиза косит наши ряды.

Расширено взаимодействие с функциями на языке Си всякими экзотическими случаями вроде многобайтовой кодировки символов по умолчанию.

Добавлены следующие два крайне полезных нововведения в форматном выводе, которых (во всяком случае, второго) ждали чуть ли не 70 лет.

Новый формат вывода AT действует как A с применением функции trim, то есть отбрасывает лишние пробелы.

Наконец!!! можно управлять печатью нуля перед десятичной точкой в вещественных числах между 0 и 1 (ранее могло быть как .5, так и 0.5 в зависимости от реализации). Для этого предназначены управляющие форматы LZP, LZS, LZ (print/suppress/default), либо ключевой параметр leading_zero=… в операторе open со значениями print, suppress, processor_defined.

Расширен синтаксис оператора namelist.

Разрешены динамически размещаемые в памяти объекты, содержащие в себе комассивы, и всё это очень сложно работает.

Добавлен механизм put with notify, обеспечивающий изменение данных в чужом адресном пространстве с отправкой уведомления. Для этого расширен синтаксис оператора комассивного присваивания опцией notify и добавлен оператор notify wait:

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
Улучшена обработка ошибочных состояний в тех случаях, когда они возникают только в части параллельных потоков.

Добавлены простые (simple) процедуры. Они отличаются от чистых (pure) процедур тем, что не только не модифицируют внешнее окружение иначе, чем через формальные параметры, но и не читают внешнее окружение иначе, чем через формальные параметры. Очевидно, полезно для выгрузки кода в GPU и в прочих неоднородных архитектурах.

Массивы разрешено индексировать массивами, задавать размерность (количество измерений) массива динамически, и вообще много разврата в стиле языка APL:

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
Долгожданное введение спецификации редукции в асинхронный оператор цикла, которое раньше было возможно только в макросах OpenMP:

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

Наконец, много малополезных возможностей, связанных с enum.

В целом, стандарт Fortran 2023 года производит положительное впечатление, а отдельных нововведений прямо-таки заждались. Но при этом вызывает беспокойство, что комитет ISO сильновато ушёл в отрыв от разработчиков компиляторов: предыдущий стандарт Fortran 2018 поддержан компиляторами только в небольшой части, а стандартом де-факто на сегодняшний день остаётся Fortran 2008. Остаётся надеяться, что хотя бы самые востребованные возможности Fortran 2023 будут реализованы достаточно быстро.

© Habrahabr.ru