Синтаксис аргумента функции Clojure
-
06-07-2019 - |
Вопрос
Я пытаюсь понять синтаксис вызова use для загрузки библиотеки:
(use 'clojure.contrib.duck-streams)
Для меня это имеет смысл, поскольку он применяет макрос для чтения цитат к clojure.contrib.duck-streams, чтобы читатель не пытался оценить эту строку.
Теперь, если я хочу использовать тег:only только для загрузки reader, почему это правильно:
(use '[clojure.contrib.duck-streams :only (reader)])
вместо того, чтобы:
(use '[clojure.contrib.duck-streams :only reader])
Я прочитал это, чтобы означать передачу этого вектора аргументов для использования, но REPL жалуется, что не знает, как создать ISeq из Symbol.Почему скобки вокруг reader?
Это также эквивалентно первой строке и допустимо:
(use '[clojure.contrib.duck-streams])
Таким образом, кажется, что 'string are'[строка] являются эквивалентными аргументами, которые я тоже не понимаю.
Решение
:only
требуется список символов.Именно так и пишется функция.Обратите внимание на строку документа для refer
, который use
использует.
refers to all public vars of ns, subject to filters.
filters can include at most one each of:
:exclude list-of-symbols
:only list-of-symbols
:rename map-of-fromsymbol-tosymbol
Это написано таким образом, чтобы вы могли указать более одного символа, если хотите.
(use '[clojure.contrib.duck-streams :only (reader writer)])
Как обсуждалось в этот недавний пост, если вы пишете функцию, которая принимает или возвращает переменное количество аргументов, хорошей идеей будет, чтобы она всегда принимала / возвращала список, вектор или набор, даже если она принимает / возвращает один элемент.Потому что:
nil
, часто используемый для представления "нулевых элементов", являетсяseq
способный.Пустые коллекции такжеseq
способный.- Два или более элемента в списке - это
seq
способный. - Имеет смысл также использовать только один элемент
seq
возможно, поместив его в сам список.
Было бы неловко, если бы случай с одним элементом был особым случаем.Это более последовательно и проще программировать, когда вы рассматриваете один элемент как своего рода вырожденный случай и добавляете его в список.
Обратите внимание, что все use
заботится о том, будет ли :only
аргумент - это разделяемый набор символов.Это означает, что все работают со списками, векторами и наборами.
(use '[clojure.contrib.duck-streams :only [reader writer]])
(use '[clojure.contrib.duck-streams :only #{reader writer}])
Один - единственный Symbol
однако это не так seq
и именно поэтому вы получаете исключение, которое вы делаете.
Загляни внутрь core.clj если вы хотите посмотреть, как все это реализовано.
Другие советы
Это не просто "parens" & # 8212; Паренс - это синтаксис для создания списка. Элемент после тега: only, как ожидается, будет списком элементов, к которым он применяется.