Дата публикации: Oct 13, 2013 6:39:50 PM
Различные виды комментария. Сейчас в Стандарте предусмотрен один вид комментариев - от символа ! до конца строки. Ну, и старый стиль - со звездочки или буквы C в начале строки. А ведь комментарии бывают разных видов: собственно комментарии, то есть пояснения к коду; отключенный ("закомментированный") код; заголовки процедур и другие "блочные" комментарии; заметки "для себя" - что сделать, в чем может быть проблема и т.п.; наконец, документация к файлу в целом. В Перле есть POD - система документирования кода, и что-то такое должно быть и в Фортране! По крайней мере, нужно синтаксически разделить комментарии на несколько видов. Например, символ ! - это просто комментарий; Все, что между =head и =cut - блочный комментарий, myhead вместо head помечает блок как личный - тогда "не-личные" блоки можно извлечь утилитами разбора POD как документацию прямо из файла! Наконец, комбинация !* пусть отключает строку кода. Собственно, все, кроме блочных комментариев, относится к личным соглашениям - но стандартизация позволила бы, например, выделять цветом отключенный код (иначе, чем комментарий). В принципе, это делается (в Вим, например), но лучше, если это - стандартная возможность.
А если блок вдруг не поддерживается компилятором, то ничего страшного не произойдет - он выдаст ошибку, после чего механическая замена решит проблему. В Вим это одна команда: :g/=head/,/=cut/s/^/!/
Стековая арифметика. Иногда длинные вычисления приводят к неразрешимой дилемме: либо использовать (и объявлять, если придерживаться процедурного стиля) вспомогательные переменные, либо писать многострочные плохо читаемые выражения. Было бы неплохо ввести стандартный стек. Для операций с ним - расширим алфавит символом @. Тогда @PUSH вычислит выражение и поместит его на стек (а можно "висячее" выражение, без присваивания, по умолчанию помещать на стек), @POP возвращает верхнее выражение (и пишем F = @POP или SIN(@POP)), для краткости можно @ трактовать как @POP. Ну и операции @+ и т.п. берут операнды со стека и помещают результат в стек. Длинное вычисление тогда может выглядеть так:
выражение; выражение; @+; выражение; @+; 2; @/; Понятно, что выражения длинные, так что они не на одной строке, а на разных. Можно ввести операции по принципу Форта или Постскрипта для работы со стеком, но это уже излишество. Кроме того, символ @ перед именем функции (без параметров) предписывает функции брать параметры из стека. Аналогично @CALL или CALL процедуры с префиксом @. Понятно, что описание элемента в стеке должно быть полным - тип, размерность - все.
Единицы измерений. Возможно, это лучше оформить как дополнительный стандарт, типа длинных строк или условной компиляции. Но для расчета реальных задач механизм единиц измерений необходим. Окружение UNITS ... END UNITS описывает единицы измерения - просто идентификаторы (базовые единицы в дополнение к стандартным), идентификаторы с инициализацией (производные единицы, типа CM = 1e-2*M, допускаются только умножения единиц и единиц на числа, а также целые степени, а может быть, и любые степени можно разрешить), массивные единицы вида PRODUCTION:: DIMENSION(1:N) для введения многочисленных единиц по номеру или номерам (например, виды производимых товаров). Наконец, можно ввести массивную единицу как набор скалярных: BASIC:: DIMENSION(3) = [M,S,KG], в частности, можно определять массивы массивов единиц. При объявлении числовой переменной можно указать атрибут UNIT(...), в скобках - скалярная или массивная единица. Со скалярами все понятно. Массив может иметь скалярную единицу измерения (тогда все элементы измеряются в ней) или массивную не большего ранга.
Дополнительные правила просты. При умножении и делении размерных величин они приводятся к базовым единицам. При сложении и вычитании - тоже, но если привести к одной комбинации базовых не удалось - происходит аварийный останов. Показатель степени должен быть безразмерным. Еще можно ввести оператор TOUNIT, принимающий единицу, возможно составную, и объект данных, и пытающийся привести его в данную единицу. Это поможет выявить ошибки, а также осуществлять ввод и вывод в удобных единицах. А может быть, оператор принимает объект данных и набор единиц, и приводит данные к ним. Ну и при определении процедур можно указывать размерности. Например, синус требует аргумент в радианах или безразмерный (синус и так полиморфный, не проблема), а если есть охота пользоваться градусами, то пожалуйста: определим градус как deg = rad * 180. / pi и соответствующее преобразование будет осуществляться автоматически.
Реализовать механизм нетрудно: базовые размерности обозначим натуральными числами, производные - парой одномерных массивов с числом элементов по числу базовых размерностей: в первом хранятся степени соответствующих базовых единиц, во втором - числовой коэффициент. При умножении степени поэлементно складываются, коэффициенты - умножаются. Проверка на безразмерность - все степени нули. При сложении массивы степеней должны совпадать, тогда слагаемые умножаются на все коэффициенты, и у суммы коэффициенты равны единице.
Цепочки сравнений. Все языки подходят в к этому простому и изящному решению проблемы плохой читаемости цепочек неравенств, и это необходимо включить в Фортран. Так, IF(0 < T < 100) THEN... лучше читается и совсем нетрудно реализовать. Правило простое: если операнд находится между двумя операторами сравнения, то он удваивается и полученные два сравнения связываются .AND.