Практические правила упорядочения аргументов функций в Clojure - PullRequest
0 голосов
/ 10 мая 2018

Каковы (если таковые имеются) правила для определения порядка функций параметров в ядре Clojure?

  • Функции типа map и filter ожидают структуру данных в качестве последнего аргумента.
  • Функции типа assoc и select-keys ожидают структуру данных в качестве первого аргумента.
  • Функции типа map и filter ожидают функцию в качестве первого аргумента.
  • Такие функции, как update-in, ожидают функцию в качестве последнего аргумента.

Это может вызывать проблемы при использовании макросов потоков (я знаю, что могу использовать as->), так какова причинаэти решения?Также было бы неплохо знать, чтобы мои функции могли как можно ближе соответствовать функциям, написанным великим человеком.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Функции, которые работают с коллекциями (и, таким образом, принимают и возвращают структуры данных, например, conj, merge, assoc, get), принимают коллекцию сначала .

Функции, которые работают с последовательностями (и, следовательно, принимают и возвращают абстракцию над структурами данных, например, map, filter), принимают последовательность last .

Осознание различия [между функциями сбора и функциями последовательности] и того, когда происходят эти переходы, является одним из наиболее тонких аспектов изучения Clojure.

(Алекс Миллер, в этой теме списка рассылки )

Это важная часть разумной работы с API-интерфейсом Clojure . Обратите внимание, например, что они занимают отдельные разделы в Clojure Cheatsheet . Это не мелочь Это имеет решающее значение для организации функций и их использования.

Может быть полезно просмотреть это описание ментальной модели при различении этих двух видов функций:

Я обычно очень хорошо знаю, когда я работаю с бетоном коллекции или с последовательностями. Во многих случаях я нахожу поток данных начинается с коллекций, затем переходит в последовательности (в результате применяя функции последовательности), а затем иногда вернуться к коллекциям когда дело доходит до отдыха (через into, vec или set). Преобразователи имеют немного изменил это, поскольку они позволяют вам отделить целевую коллекцию от преобразования и, следовательно, гораздо легче оставаться в Коллекции все время (если вы хотите), применяя с преобразователя.

Когда я собираю или работаю над коллекциями, обычно код построить его "близко" и типы коллекции известны и очевидно. Как правило, последовательные данные, скорее всего, будут векторами и кон хватит.

Когда я думаю о «последовательностях», я очень редко операция, как "добавить последний" - вместо этого я думаю, что во всей коллекции термины.

Если мне нужно сделать что-то подобное, то я, вероятно, преобразовал бы вернуться к коллекциям (via into или vec) и снова использовать Con.

FAQ Clojure содержит несколько хороших практических правил и техник визуализации для получения интуиции коллекции / первый аргумент против последовательности / последнего аргумента.

0 голосов
/ 10 мая 2018

Вместо того, чтобы это был вопрос только для ссылок, я вставлю цитату ответа Рича Хикки на вопрос Usenet "Практические правила порядка аргументов" :

Одним из способов думать о последовательностях является то, что они читаются слева, и кормят справа:

<- [1 2 3 4] </p>

Большинство функций последовательности используют и создают последовательности. Так что способ визуализации в виде цепочки:

карта <- фильтр <- [1 2 3 4] </p>

и один из способов думать о многих функциях seq состоит в том, что они параметризованный некоторым образом:

(карта f) <- (пред. Фильтра) <- [1 2 3 4] </p>

Итак, функции последовательности берут свои источники в последнюю очередь, а любые другие параметры перед ними, а частично позволяет прямую параметризацию как указано выше. Существует традиция этого в функциональных языках и Лепечет.

Обратите внимание, что это не то же самое, что последний первичный операнд. Некоторые функции последовательности имеют более одного источника (concat, чередовать). Когда функции последовательности являются переменными, это обычно в их источники.

Я не думаю, что списки переменных arg должны быть критерием для основной операнд идет. Да, они должны прийти последними, но по мере эволюции из ассоциативных / диссоциальных шоу, иногда переменные аргументы добавляются позже.

То же самое частичное. Каждая библиотека в конечном итоге заканчивается метод независимого частичного связывания. Для Clojure это # ​​().

Что тогда является общим правилом?

Первичные операнды коллекции идут первыми. Так можно написать -> и его род, и их положение не зависит от того, имеют ли они переменные параметры арности. В ОО есть такая традиция языки и CL (значение слота CL, aref, elt - фактически тот, который спотыкает меня чаще всего в CL это gethash, который не согласуется с те).

Итак, в конце концов, есть 2 правила, но это не все. Функции последовательности берут свои истоки и функции сбора сначала возьмите их основной операнд (коллекцию). Не то, что нет тут и там есть несколько перегибов, которые мне нужно сгладить (например, set / Выбрать).

Надеюсь, это поможет сделать его менее поддельным,

Rich

Теперь, как я различаю «функцию последовательности» и «функцию сбора», мне не очевидно. Возможно, другие могут объяснить это.

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