Как я могу применить doc-функцию clojure к последовательности функций - PullRequest
2 голосов
/ 01 декабря 2011

Я пытался сделать что-то, что мне показалось бы простым, но оказалось, что это не так, и я думаю, что решение может дать мне более глубокое понимание замыкания, поэтому я решил спросить здесь.

Я хочу, чтобы можно было запустить следующую команду из REPL:

(map #(doc %) v)

, где v - это вектор ... чего-то, я не уверен, что. Цель состояла в том, чтобы напечатать строки документа для некоторой последовательности функций, но я не уверен, как выразить этот вектор. Я попробовал пару вещей: (Я выберу несколько функций наугад)

[+ - first set]
['+ '- 'first 'set]
[`+ `- `first `set]
[(var +) (var -) (var first) (var set)]
[`~+ `~- `~first `~set]

Нет работы. Я также попытался apply функцию doc, но это не работает, поскольку doc является макросом и поэтому не может быть аргументом для apply. Чего мне не хватает?

Ответы [ 3 ]

3 голосов
/ 02 декабря 2011
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f)))
1 голос
/ 02 декабря 2011
(defn my-doc [v] (-> v meta :doc))

Эта функция берет метаданные из var, а затем получает строку документа из метаданных.Вы можете отобразить его на последовательность переменных:

(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings

или короче:

(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings

Это не работает для специальных форм, поскольку на них не ссылаются переменные.*

1 голос
/ 02 декабря 2011

В Clojure 1.2 вы можете использовать функцию print-doc:

(print-doc #'fisrt)

вот так

(map print-doc [#'fisrt #'+])

#'fisrt совпадает с (var first).

Обратите внимание, что это не будет работать для специальных форм: (doc def) работает, но (print-doc # def) `дает:

java.lang.Exception: Unable to resolve var: def in this context (NO_SOURCE_FILE:7)

Это потому, что специальные формы не определены в vars.Вы можете увидеть, как для них работает документ, используя macroexpand-1:

user=> (macroexpand-1 '(doc def))
(clojure.core/print-special-doc (quote def) "Special Form" (clojure.core/special-form-anchor (quote def)))

В Clojure 1.3 print-doc перемещается в пространство имен clojure.repl и является закрытым, поэтому вы не можете выполнить его напрямую.Вы можете ввести ns:

user=> (in-ns 'clojure.repl)
clojure.repl=> (print-doc (meta #'first))
clojure.repl=> (map #(print-doc (meta %)) [#'first #'+])

Как видите, Clojure 1.3 требует явного получения метаданных.

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

clojure.repl=> (defn my-print-doc [m] (print-doc m))
user=> (clojure.repl/my-print-doc (meta #'first))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...