Подтвердить что ты не робот

Когда использовать let vs. if-let in Clojure

Когда используется if-let вместо let, чтобы код выглядел лучше и имел ли он какое-либо влияние на производительность?

4b9b3361

Ответ 1

Я думаю, if-let следует использовать, когда вы хотите ссылаться на значение условия if в параметре then часть кода:

то есть. вместо

(let [result :foo]
  (if result
    (do-something-with result)
    (do-something-else)))

вы пишете:

(if-let [result :foo]
  (do-something-with result)
  (do-something-else))

который немного опрятен и позволяет вам отступать на следующий уровень. Что касается эффективности, вы можете видеть, что расширение макроса не увеличивает накладные расходы:

(clojure.core/let [temp__4804__auto__ :foo]
  (if temp__4804__auto__
    (clojure.core/let [result temp__4804__auto__]
      (do-something-with result))
    (do-something-else)))

Это также иллюстрирует, что привязка не может быть указана в части "else" кода.

Ответ 2

Хорошим вариантом использования для if-let является удаление необходимости использования анафоры. Например, язык программирования Arc предоставляет макрос с именем aif, который позволяет связать специальную переменную с именем it внутри тела формы if, когда данное выражение оценивает логическое значение true. Мы можем создать одно и то же в Clojure:

(defmacro aif [expr & body]
  `(let [~'it ~expr] (if ~'it (do [email protected]))))

(aif 42 (println it))
; 42

Это хорошо и хорошо, за исключением того, что анафора не гнездится, но if-let делает:

(aif 42 (aif 38 [it it]))
;=> [38 38]

(aif 42 [it (aif 38 it)])
;=> [42 38]

(if-let [x 42] (if-let [y 38] [x y]))
;=> [42 38]