Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] Pure functions


Автор: valvliv 17.2.2006, 20:14
Это опять я со своими изысканиями smile

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

http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/IBMp690/IBM/usr/share/man/info/en_US/xlf/html/lr82.HTM

Что меня там смущает: зачем вообще у такой функции указывается аргумент, если он как бы не предполагается к использованию?? И нет ли проще формы таких функций, как вот в Матлабе, когда у функции пустые скобки при отсутствии аргумента?

Л.

Автор: Cr@$h 18.2.2006, 01:00
Цитата(valvliv @ 17.2.2006, 21:14 Найти цитируемый пост)
Это опять я со своими изысканиями

smile
Цитата(valvliv @ 17.2.2006, 21:14 Найти цитируемый пост)
Возникла необходимость написать простую функцию без входных аргументов, что называют pure.

Немного поясню, что такое чистые процедуры. Это не обязательно те, которые не имеют параметров ваще. Причем не имеющие параметров могут быть и не чистыми. smile
А теперь по-русски. Некоторые процедуры имеют побочные эффекты, как то, например:
  • процедуры, которые помнят значения и состояния своих внутренних переменных (те, что имеют атрибут save, инициализированы через оператор data или инициализированы при объявлении -- что-то из этого мы уже проходили в топике про save smile );
  • функции, которые меняют значения своих входных параметров (подпрограмма может менять их значения и оставаться чистой);
  • процедуры, которые используют глобальные переменные.
Потому такие процедуры не являются чистыми. Теперь видно, что даже не имеющие параметров процедуры могут быть не чистыми.
Если интуитивно, то можно сказать, что такие процедуры не совсем предсказуемы, т.е. на одном и том же наборе данных могут выдавать различные результаты, например, по перечисленные выше процедурам. Они не обладают целостностью, зависимы от внешнего мира, так сказать.
Что в них плохого? Их нельзя выполнять параллельно. Ведь если, например, внутренние значения сейвятся до следующего вызова, то последовательное выполнение двух процедур по результатам может отличаться от их параллельного выполнения: в первом случае вызов оставит следы и повлияет тем самым на второй вызов.
Именно из-за параллельных соображений они были введены.
Немного чистого формализма.
  • указание на чистоту процедуры делает атрибут pure:
    Код

    pure subroutine Bla( a, b, c )
        ...
    end subroutine Bla

    pure real function BlaBla( a, b, c )
        ...
    end function BlaBla
  • функция не меняет своих параметров и для всех параметров кроме формальных процедур и ссылок обязательно устанавливает вид связи in;
  • подпрограммы меняют только out- и inout-параметры и должны указывать вид связи для всех параметров;
  • все встроенные функции чисты + подпрограмма MVBits;
  • внутренние переменные не должны сохраняться: иметь атрибут save, инициализироваться в операторах data или при своем объявлении;
  • нельзя менять глобальные переменные и переменные, ассоциированные с ними (например через equivalence как-то);
  • нельзя ссылаться на глобальные переменные и переменные, ассоциированные с ними (например через equivalence как-то): например, указывать на них (не пальцем, а переменной ссылочного типа);
  • не должно быть операцций ввода/вывода;
  • нельзя использовать операторы stop и pause (последний исключен);
  • чистые процедуры (скорее только функции) можно вызывать в операторах forall;
  • чистые могут вызывать себе подобных -- тоже чистых, и выступать для них в качестве формальных параметров -- должны внутри такой процедуры иметь явный интерфейс с указанием pure;
  • элементные процедуры по определению являются чистыми;
  • процедуры для операторов неявно могут являться чистыми:
    • ведь у функций-опраций для параметров и так указаны виды связи in;
    • ведь у подпрограмм-присваиваний все виды связи указаны обязательно;
    • потому такие процедуры могут оказаться чистыми, если выполнены другие условия;
    • можно специально у таких процедур указывать атрибут pure, если хотим обеспечить их чистоту;
  • невстроенные чистые процедуры (как и любые другие невстроенные) нельзя использовать в выражениях инициализации -- очень популярный миф, F03 допускает использование при инициализации любых встроенных функций, например
    Код

    real, parameter :: pi = atan( 1.0 ) * 4.0
  • рекурсивные процедуры могут быть и чистыми, т.к. вызывают обычно только себя -- чистых.
Чистоту процедур можно использовать например при:
  • вызове внутри оператора или конструкции forall или другой чистой процедуре;
  • подстановке как параметра в другую чистую процедуру;
  • повышении надежности -- контроль со стороны компилятора, чтобы не было побочных эффектов у процедуры;
  • использовании параллелизации.
По-моему, такие процедуры называются еще thread-safe (or not smile ).
Цитата(valvliv @ 17.2.2006, 21:14 Найти цитируемый пост)
Что меня там смущает: зачем вообще у такой функции указывается аргумент, если он как бы не предполагается к использованию?? И нет ли проще формы таких функций, как вот в Матлабе, когда у функции пустые скобки при отсутствии аргумента?

Теперь и сама ответ знаешь: пиши простых процедур сколько душе угодно безо всяких параметров. Рекомендую только указывать при вызове скобочки, маленькие такие, например,
Код

x = WithoutParameters()

вместо
Код

x = WithoutParameters

дабы не путать с переменными. И эти процедуры не обязаны быть чистыми, правда? Но право быть такими имеют. А чистота -- "совсем другая тема". smile
За ресурс, по которому смотрела, уважаю. IBM -- это, конечно, серьезно. Собссенно, Бэкус, создатель языка, оттуда. Можешь также зайти и в раздел компьютерной литературы по http://forum.vingrad.ru/index.php?showtopic=56761 на Vingrad.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)