Информация об изменениях

Сообщение Re[115]: Мнение: объектно-ориентированное программирование — от 14.11.2019 17:09

Изменено 14.11.2019 18:11 AlexRK

Re[115]: Мнение: объектно-ориентированное программирование —
Здравствуйте, samius, Вы писали:

S>>>Что скажешь о чистоте по одной лишь сигнатуре с учетом того, что printf "чистая"? Вероятно, тоже будет чистой.

ARK>>В С/C++ нет сигнатуры, определяющей чистоту. Поэтому флагом чистоты может быть только документация. Если там сказано, что эта функция чистая — значит, чистая. Если не сказано — значит, мы должны подозревать грязь. Можно строить предположения о чистоте из других факторов, но это самый ненадежный способ, ибо это та самая "чуйка", проверить которую в общем случае нельзя.
S>То есть, одной сигнатуры недостаточно.

Достаточно. Эта функция будет грязной, т.к. не указано обратное. И мы должны ее таковой считать и обращаться с ней соответствующим образом.

А вот если у синуса не будет явного указания, что он чист — то это хуже. Умом мы вроде как понимаем, что синус должен быть чистым, но это не подтверждается декларацией. Формально мы должны или считать его грязным, или смотреть исходники. А в исходниках, если они есть, искать грязь, т.е. функции, аксиоматически постулированные как грязные (если не найдем — значит можем заключить, что синус "декларативно" чист).

ARK>>В википедии, если не ошибаюсь, сказано об эффектах, которые видны окружению. Поправь, если я не прав. Стало быть, в подходящем окружении ввода-вывода не будет, даже если мы будем дергать соответствующие функции. Так?

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

Не просто "для некого набора сайд-эффектов можно построить подходящее окружение, что сайд-эффекты не будут себя проявлять", а "сайд-эффекты как таковые не существуют в подходящем окружении", потому что само определение сайд-эффектов завязано на окружение. Получается, в таком "подходящем окружении" функция, согласно википедии, будет чистой. А в другом окружении — нет. То есть википедийное определение чистоты имеет в себе зависимость от окружения.

S>Но что нам делать с тем, что программа должна написать нечто вычисленное в файл/консоль, что мы хотим увидеть? У нее же должно быть какое-то желаемое наблюдаемое поведение кроме вырожденного (никакого)? Стоит избавиться от всех сайд-эффектов, и программу можно даже не писать, не то что бы компилировать и запускать.


Можно сказать, что выполнение данной программы в таком окружении не имеет эффекта. Собственно, любой программе нужно какое-то специфическое окружение, на которое она рассчитана. Главный вопрос не в этом, а в том, должно ли окружение влиять на формальные рассуждения о семантических свойствах программы. Согласно википедийным определениям — должно. Мне это кажется неправильным.
Re[115]: Мнение: объектно-ориентированное программирование —
Здравствуйте, samius, Вы писали:

S>>>Что скажешь о чистоте по одной лишь сигнатуре с учетом того, что printf "чистая"? Вероятно, тоже будет чистой.

ARK>>В С/C++ нет сигнатуры, определяющей чистоту. Поэтому флагом чистоты может быть только документация. Если там сказано, что эта функция чистая — значит, чистая. Если не сказано — значит, мы должны подозревать грязь. Можно строить предположения о чистоте из других факторов, но это самый ненадежный способ, ибо это та самая "чуйка", проверить которую в общем случае нельзя.
S>То есть, одной сигнатуры недостаточно.

Достаточно. Эта функция будет грязной, т.к. не указано обратное. И мы должны ее таковой считать и обращаться с ней соответствующим образом.

А вот если у синуса не будет явного указания, что он чист — то это хуже. Умом мы вроде как понимаем, что синус должен быть чистым, но это не подтверждается декларацией. Формально мы должны или считать его грязным, или смотреть исходники. А в исходниках, если они есть, искать грязь, т.е. функции, аксиоматически постулированные как грязные (если не найдем — значит можем заключить, что синус "декларативно" чист).

ARK>>В википедии, если не ошибаюсь, сказано об эффектах, которые видны окружению. Поправь, если я не прав. Стало быть, в подходящем окружении ввода-вывода не будет, даже если мы будем дергать соответствующие функции. Так?

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

Не просто "для некого набора сайд-эффектов можно построить подходящее окружение, что сайд-эффекты не будут себя проявлять", а "сайд-эффекты как таковые не существуют в подходящем окружении", потому что само определение сайд-эффектов завязано на окружение. Получается, в таком "подходящем окружении" функция, согласно википедии, будет чистой. А в другом окружении — нет. То есть википедийное определение чистоты имеет в себе зависимость от окружения.

S>Но что нам делать с тем, что программа должна написать нечто вычисленное в файл/консоль, что мы хотим увидеть? У нее же должно быть какое-то желаемое наблюдаемое поведение кроме вырожденного (никакого)? Стоит избавиться от всех сайд-эффектов, и программу можно даже не писать, не то что бы компилировать и запускать.


Можно сказать, что выполнение данной программы в таком окружении не имеет эффекта. Собственно, любой программе нужно какое-то специфическое окружение, на которое она рассчитана. Главный вопрос не в этом, а в том, должно ли окружение влиять на формальные рассуждения о семантических свойствах программы. Согласно википедийным определениям — должно. Мне это кажется неправильным.


UPD. Кстати, я, пожалуй, соглашусь, что putStr является чистой функцией. Я поковырял код и не нашел улик, доказывающих обратное. Например, вот этот код

import System.IO.Unsafe

putStrLn2 :: String -> IO ()
putStrLn2 (s) = do
    let q = unsafePerformIO $ do { putStrLn " backdoor "; return " 1 "; }
    putStrLn (s ++ q)

putStrLn1 = putStrLn2 "qwerty"

main = do
    putStrLn1
    putStrLn1


выдает:

qwerty backdoor
1
qwerty 1


т.е. можно считать результат вызова putStr закешированным. Значит, "оторвать" action от IO-функции таки можно, как минимум, теоретически. Как оно на самом деле происходит — непонятно, потому что никак нельзя вызвать какую-то "отладочную печать" изнутри функции. По крайней мере я не знаю, как это сделать. Через unsafePerformIO вот такую картину показывает.

Поэтому вопрос о чистоте putStr я закрываю — я согласен, что она чиста, в том числе в соответствии с моей трактовкой чистоты. Другой вопрос, что нам эта ее чистота не так уж сильно помогает, потому что нам интересно в основном то, что делает ее результат (action), а не то, что делает она сама (просто возвращает action).