Как работает это расширение макросов Clojure? - PullRequest
1 голос
/ 02 июня 2019

Я нахожусь в процессе изучения Clojure, через «Clojure для Храброго и Истинного».

На уроках макросов я пробовал следующий макрос,

(defmacro report
  [to-try]
  `(let [result# ~to-try]
     (if result#
       (println (quote ~to-try) "was successful:" result#)
       (println (quote ~to-try) "was not successful:" result#))))

И нижеВот пара моих экспериментов с макросом и соответствующими выводами.

1

(map #(report %) ['(= 1 2) '(= 1 1)])
; p1__26622# was successful: (= 1 2)
; p1__26622# was successful: (= 1 1)

2

map #(report %) ['false 'true])
; p1__26612# was not successful: false
; p1__26612# was successful: true

И мои вопросы:

  • Почему в первом случае макрос печатал true для обоих значений?
  • В моем понимании второе точно соответствует первому.Но почему это дает другой результат?

1 Ответ

4 голосов
/ 02 июня 2019

Почему в первом случае макрос печатал true для обоих значений?

Ваш макрос report получает списки в кавычках в качестве входных данных, а не выражения, которые могут быть оценены как истина / ложь. Любой список правдив, даже если он содержит выражение, которое оценивается как ложное. Это даст вам ожидаемый результат:

(report (= 1 2)) ;; evaluates to false

В моем понимании второе в точности эквивалентно первому. Но почему это дает другой результат?

Это не совсем эквивалентно, потому что в первом примере рассматриваются списки, а во втором - цитируемые булевы. Ваш второй пример оценивает 'false как ложное, потому что if относится к нему:

(if 'false 0 1) => 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...