Как стать автором
Обновить

Комментарии 21

Фортран это всегда круто, как стимпанк и альтернативная история...

Так и представляется реализация Фортрана для механической разностной машины из романа Стерлинга и Гибсона.

Это уже какой-то ретрокиберпанк, в котором хакеры охотятся за секретной перфокартой с секретным кодом на Фортране.

Или как изучать немецкий после английского.

Выбросы энергии в ноосферу говорят: кто-то опять применил тёмное искусство некромантии!

То есть у языка ФОРмул до 2024 года не было условных выражений?
Здорово, да :)

Было merge(a, 0.0, a>0.0), а теперь в качестве альтернативы добавили привычный по другим языкам синтаксис (a>0.0 ? a : 0.0).

Не совсем так, merge – обычная функция, а ? - специальная форма. В первом случае вычисляются значения всех трёх аргументов, поэтому такая, например, штука не пройдёт:

merge(a(i), 0.0, i >= 1)

Если функция a объявлена как pure, т.е. не имеет побочных эффектов, то уже в режиме -O1 компилятор gfortran не будет вызывать ее без необходимости:
https://godbolt.org/z/cKcdMrdxP
А иначе, да, стандарт требует вычисления всех аргументов функции.
Но в большинстве случаев gfortran (в отличие от ifort и ifx, как ни парадоксально) очень хорошо оптимизирует merge.

Имелся в виду массив.

А, тогда тем более будет оптимизировано.

program m

  implicit none

  real :: a(2) = 0.
  integer :: i = 0

  print *, merge(a(i), 0.0, i>=1)

end program m
gfortran merge.f90 -omerge -O3 -Wl,-ld_classic -ftree-vectorize -march=native -flto -fcheck=bounds
./merge
At line 8 of file merge.f90
Fortran runtime error: Index '0' of dimension 1 of array 'a' below lower bound of 1

Error termination. Backtrace:
#0  0x10b38aaae
#1  0x10b38b7a5
#2  0x10b38bd15
#3  0x10aa72eb9
#4  0x10aa72ede
#5  0x7ff80bba9385

Ну и вообще нельзя полагаться на оптимизацию в принципиальном вопросе.

Ну так вы же специально указали -fcheck=bounds. Без него (просто -O3) у меня gfortran 13.2 выводит
0.00000000E+00
без каких-либо ошибок.

Да и не понимаю я, о чем мы спорим. Я просто привел пример, каким был аналог тернарного условного оператора в предыдущих версиях Fortran.

Без check программа просто тихо лезет в чужую память, что не очень хорошо и не всегда возможно.

Да и не понимаю я, о чем мы спорим. Я просто привел пример, каким был аналог тернарного условного оператора в предыдущих версиях Fortran.

А я уточнил, что это не совсем аналог.

Там по ассемблерному коду видно, что компилятор оптимизирует до просто print *, 0.0 и никуда не лезет. И даже в более сложных случаях, если нет побочных эффектов, merge заменяется на сравнение и условный переход, т.е. полностью аналогично тернарному условному оператору.

Условная операция, будучи специальной формой, не вычисляет неактивную ветку, это написано в её определении. Любая функция по своей семантике вычисляет все свои входные аргументы, а merge формально является обычной функцией. Иногда оптимизатор может убрать лишнюю работу, но это не гарантированное поведение, и программа не должна от него зависеть. Это важная семантическая разница.

В SICP прямо даётся такой пример. Там бесконечную рекурсию так забабахали, заменив условную специальную форму на условную функцию.

А можно пользователям fortran 77 объяснить о чем речь? И куда делись мои .le. .lt. .eq. и прочие?

Вместо .le., .lt., .eq. последние 30 лет можно писать банальные <=, <, == :)

merge – функция, сливающая вместе два массива, беря элементы из того или другого по условию. В частном случае может работать со скалярными величинами.

Условные выражения для конвейерной обработки массивов - это уже довольно древняя фича Фортрана, ей без малого лет 30, если не 40. ForAll, Where, Sum, и прочие спецфункции для массивов.


Первые в истории программирования и планеты Земля рабочие условные операторы выглядели так:

      IF(a) 1, 2, 3
1 ... 
      GOTO 4
2 ...
      GOTO 4
3 ...
      GOTO 4
4 ...
      IF(b>0) GOTO 666
...

666   STOP 'b>0!'

Если а<0, то переход происходит на метку 1, если a=0, то на метку 2, если a>0 - то на метку 3.

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

Но уже лет через 10 появились обычные ifы.

На этом фоне заявления "C++ умирает" смотрятся особенно забавно. :)

С точки зрения новомодных ЯП Фортран и С++ - ровесники, подобно тому как для 15-летней кобылки древними стариками выглядят как 60-летний, так и 80-летний деды.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории