Когда использовать «постоянно» в clojure, как и когда оцениваются его аргументы? - PullRequest
15 голосов
/ 25 октября 2010

В принятом ответе на другой вопрос Установка "постоянных" Clojure во время выполнения используется функция clojure constantly.

Определение constantly выглядит так:

(defn constantly
  "Returns a function that takes any number of arguments and returns x."
  {:added "1.0"}
  [x] (fn [& args] x))

Строка документа говорит о том, что она делает, но не о том, зачем ее использовать.

В ответе, приведенном в предыдущем вопросе, постоянно используется следующее:

(declare version)

(defn -main
  [& args]
 (alter-var-root #'version (constantly (-> ...)))
 (do-stuff))

Таким образом, функция, возвращаемая постоянно, напрямую оценивается по ее результату. Я не понимаю, как это полезно. Я, вероятно, не понимаю, как x будет оцениваться с и без того, чтобы быть завернутым в "постоянно".

Когда мне следует использовать constantly и зачем это нужно?

1 Ответ

12 голосов
/ 26 октября 2010

Функция constantly полезна, когда API ожидает функцию, а вам нужна только константа.Это имеет место в примере, приведенном в вопросе.

Большинство функций alter-* (включая alter-var-root) используют функцию, позволяющую вызывающей стороне изменять что-либо на основе своего старого значения.Даже если вы просто хотите, чтобы новое значение равнялось 7 (без учета старого значения), вам все равно нужно предоставить функцию (предоставление только 7 приведет к попытке оценить его, но не удастся).Таким образом, вы должны предоставить функцию, которая просто возвращает 7. (constantly 7) производит именно эту функцию, экономя усилия, необходимые для ее определения.

Редактировать: Что касается второй части вопроса, constantly - это обычноефункция, поэтому ее аргумент вычисляется до того, как будет создана постоянная функция.Поэтому (constantly @myref) всегда возвращает значение, на которое ссылается myref во время вызова constantly, даже если оно будет изменено позже.

...