Определение нечистых функций в Clojure

#clojure #functional-programming

#clojure #функциональное программирование

Вопрос:

Я изучаю Clojure и функциональное программирование в целом (исходя из python). В Clojure можно создавать нечистые функции, поскольку вы можете использовать slurp и другие средства ввода. Есть ли способ легко идентифицировать нечистые функции в Clojure, или это практика, чтобы просто сохранить эти функции в отдельном разделе кода?

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

1. Не совсем, нет. Как бы вы определили «нечистую функцию», в любом случае? Является memoize нечистым? Как насчет функции, возвращаемой memoize ? Или ссылочно прозрачная функция, которая использует переходные процессы внутри?

2. Clojure не является чистым языком FP, как, например, Haskell. Если это важно для вас, то Clojure — неправильный выбор.

3. @MichielBorkent: для меня не важно быть чистым, я просто подумал, что было бы интересно, если бы можно было разделить чистые и нечистые разделы.

Ответ №1:

Теоретически, нет способа определить, вызывает ли функция побочные эффекты или нет (из-за теоремы Райса). Таким образом, вероятно, невозможно отличить чистые функции от нечистых функций. Конечно, может быть способ проверить, является ли функция определенно нечистой на синтаксическом уровне, но я сомневаюсь, что это действительно поможет на практике.

Ответ №2:

Существует довольно распространенное соглашение о завершении имени функции символом bang (например. swap! ), когда эта функция небезопасна для использования внутри транзакции STM. Это включает в себя ввод-вывод и множество типов побочных эффектов, поэтому здесь есть некоторое совпадение с примесью, однако многие нечистые функции также полностью безопасны.

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

1. Пожалуйста, измените формулировку части «небезопасно для использования в STM», потому что swap является частью STM 😉 это абсолютно безопасно, у него просто есть контролируемые побочные эффекты.

2. @ArthurUlfeldt Формулировка уже очень похожа на фразу в стандарте библиотечного кодирования: «Используйте взрыв! только для вещей, небезопасных в транзакции STM.» Поэтому я не уверен, как я могу это улучшить.

3. Я действительно не хочу видеть людей, избегающих использования swap! изнутри dosync блоков, потому что они думают, что это будет «небезопасно». Мы должны быть осторожны, оставляя заявления на подобных сайтах, которые запускают подобные слухи. Вы могли бы выбрать пример, который на самом деле небезопасен для использования внутри STM, давая понять, что это не относится ко всем функциям, имя которых заканчивается на !

4. @ArthurUlfeldt Насколько я понимаю, swap! может выполняться несколько раз в dosync блоке и может изменять atom несколько раз, что на самом деле не то, чего хотят люди. Это неправильно?

5. Это неверно. Все взаимодействия с агентами и атомами сохраняются до фиксации транзакции и отправляются агентам и атомам ровно по одному. В особом случае, когда они отправляются с нулевым количеством ошибок транзакции. Они гарантированно безопасны.