Как я могу проверить, есть ли у функции побочные эффекты в Clojure? - PullRequest
10 голосов
/ 02 января 2011

Есть ли функция или макрос, где я могу сделать следующее:

(has-side-effects?  my-function  my-function-args)

: или что-то подобное, которое может вернуть true или false ,или {: побочные эффекты true / false,: результат return_value)

Мне просто нужен простой способ проверить, какие функции не имеют побочных эффектов.

Ответы [ 4 ]

7 голосов
/ 13 марта 2011

В общем случае это невозможно (если вам также не удается решить проблему остановки .... :-))

Однако существуют различные методы, которые вы могли бы рассмотреть в определенных обстоятельствах:

  • Создайте «белый список» функций, которые, как вы знаете, не имеют побочных эффектов - например, большинство основных API Clojure не имеют побочных эффектов
  • Используйте метаданные для обозначения ваших собственных функций, как это было предложено Гораном
  • Используйте аннотации для классов / функций Java, которыми вы управляете
  • Используйте часы на ссылках Clojure (с add-watch ), если вы хотите проверить наличие побочных эффектов на конкретных ссылках Clojure
7 голосов
/ 02 января 2011

Если это одна из ваших функций добавить метаданные для отметки, если они имеют побочные эффекты.

Затем вы можете проверить это с помощью ((meta f) :side-effects)

Если это сторонняя функция , я не знаю ни одного способа (кроме изменения их кода для использования решения, описанного выше).

На самом деле, есть даже тогда, но это не такхорошенький.Вы можете обернуть функцию своей собственной, которая имеет метаданные.

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

Однако имейте в виду:

Это просто не будет работать для функций, которые принимают другиефункционирует как параметры.Вот пример: есть ли у звонка map побочные эффекты?

Здесь его нет: (map inc [1 2 3])

Но здесь есть: (map println [1 2 3])

Посколькупереданная функция может иметь или не иметь побочные эффекты.

5 голосов
/ 02 января 2011

Clojure не является чисто функциональным языком. Это не навязывает чистоту функциям, использующим систему типов, как это делает Haskell. Таким образом, no , нет (простого) способа узнать, является ли функция свободной от побочных эффектов или нет в Clojure.

0 голосов
/ 02 января 2011

Нет, не существует простого способа получить ответ "да" или "нет" наверняка. Однако вы можете ответить «нет» или «возможно», определив, возможно ли даже побочный эффект в данном коде.

Если вы видите какие-либо признаки того, что существует вероятность побочного эффекта, тогда вы можете вернуть «возможно». В противном случае вы бы вернули «нет», если побочные эффекты невозможны.

Вы можете пройтись по коду и сделать предположение, отыскивая формы, которые указывают на возможный побочный эффект. Любые 'print', 'dosync', установщики Java или новые объекты Java будут означать, что возможны побочные эффекты.

В целом, ответ да / нет невозможен, о чем я знаю. Тем не менее, нет / может быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...