Смысл syntax-quote
, unquote
и unquote-splicing
заключается в том, чтобы помочь разработчику писать макросы.
Например, без syntax-quote
и unquote
вам придется написать
user=> (list :a extra-values)
(:a [1 2 3 4])
вместо:
user=> `(:a ~extra-values)
(:a [1 2 3 4])
В первом случае читателю (читателю-человеку, а не реплею) труднее понять, как будет выглядеть получающаяся форма,тогда как в последнем случае сохраняется «форма» результирующей формы.
Так что, если вместо vector
[1 2 3 4]
мы хотим объединить содержимое extra-values
как элементы в результирующую форму?Нам нужно unquote-splicing
, чтобы мы могли написать:
user=> `(+ 100 200 ~@extra-values)
(clojure.core/+ 100 200 1 2 3 4)
вместо:
user=> (concat `(+ 100 200) extra-values)
(clojure.core/+ 100 200 1 2 3 4)
И снова версия unquote-splicing
позволяет коду напоминать «форму» получающегосяформируется при вычислении кода, тогда как в последней версии «форма» теряется в шуме apply
и list
.
Оба эти примера очень просты, но syntax-quote
и друзья действительноприходят сами по себе при написании более сложных макросов.
Возвращаясь к вашему вопросу о том, почему вы не можете написать (+ 1000 ~@extra-values)
?У нас уже есть эта функциональность в apply
(с некоторыми дополнительными ограничениями):
user=> (apply + 1000 extra-values)
1010