Как предотвратить оценку аргументов функции clojure? - PullRequest
1 голос
/ 04 мая 2020
(defn fun
  [& args]
  (println args))
(fun (+ 1 1) (+ 1 1))

Я хочу, чтобы вывод fun был ((+ 1 1) (+ 1 1)). Я знаю, что цитирование формы может сделать ее неоцененной. Но когда я цитирую args, как показано ниже,

(defn fun
  [& args]
  (println 'args))

, то получается args. Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 04 мая 2020

Clojure, как и все ленивые языки (которые почти все), оценивает аргументы вызова функции перед вызовом функции. Когда вы вызываете:

(foo (+ 1 1) (+ 1 1))

, сначала оцениваются аргументы

(foo 2 2)

, затем вызывается функция, поэтому в вашем foo, args есть (2 2). Нет никакой связи с формами, которые произвели эти значения.

Если вы хотите предотвратить оценку, вам нужно указать до оценки, то есть в форме вызова:

(defn foo [& args]
  (println args))

(foo '(+ 1 1) '(+ 1 1))
1 голос
/ 05 мая 2020

Одна хитрость, которая иногда удобна, когда требуется более одного аргумента, который нужно заключить в кавычки, - это обернуть все в вектор, чтобы избежать цитирования каждого аргумента в отдельности. Рассмотрим:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test) )

(defn foo
  [args]  ; not rest args. no `&` present!
  (spyx args))

(dotest
  (foo (quote [(+ 1 2) (+ 3 4)])) ; sometimes this is easier to read & manipulate
  (foo '[(+ 1 2) (+ 3 4)]) ; this is a reader shortcut for the above
  (let [x 4]
    (foo `[(+ 1 2) (+ 3 ~x)]) ; backquote is handy, and always fully-qualifies Var names
  ))

с результатом

-------------------------------
   Clojure 1.10.1    Java 14
-------------------------------

Testing tst.demo.core
args => [(+ 1 2) (+ 3 4)]
args => [(+ 1 2) (+ 3 4)]
args => [(clojure.core/+ 1 2) (clojure.core/+ 3 4)]

Мы видим, что нам нужно только заключить в кавычки вектор переноса, а не каждый элемент внутри него. Это также показывает, что одиночная кавычка является ярлыком для чтения специальной формы (quote ...).

Последний пример показывает, что мы можем использовать синтаксическую кавычку (то есть обратную цитату). Это позволяет нам вставлять значения в шаблон как здесь x. Поскольку он предназначен для макросов, он добавляет пространство имен ко всем ссылкам на Var (т. Е. Функция + здесь).

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