Люди,
Я начал изучать clojure несколько лет назад, и у меня есть один вопрос.
В этой функции:
(defn print-coords [coords]
(let [lat (first coords)
lon (last coords)]
(println (str "Latitude: " lat " - " "Longitude: " lon))))
=> #'dev-projects.core/print-coords
Я определяю глобальную функцию с одним параметром.
Но если я вызову эти аргументы:
(print-coords [54 32])
Latitude: 54 - Longitude: 32
=> nil
Я получу успешный ответ.
Почему это работает? Оригинальная функция не должна работать только с одним аргументом?
Я думаю, вы путаете (print-coords [53 32])
с (print-coords 54 32)
.
В первом случае coords
— это вектор [53 32]
, first
которого равен 54
-> lat
, а second
действительно равен lon
32
. Возвращаемое значение правильно nil
, так как println
возвращает nil
.
Однако:
user=> (print-coords 54 32)
Execution error (ArityException) at user/eval141 (REPL:1).
Wrong number of args (2) passed to: user/print-coords
Вопрос в том, как [coords]
в определении совместимо с [53 32]
в вызове.
Параметры определения заключаются в квадратные скобки, но аргументы вызова функции не заключаются в знаки препинания. Таким образом, [53 32]
буквально является вектором, переданным в качестве аргумента 1 для вызова функции. [53 32]
соответствует coords
.
Кстати, print-coords можно было бы определить более идиоматически следующим образом:
(defn print-coords [[lat lon]]
(println (str "Latitude: " lat " - " "Longitude: " lon)))
Это по-прежнему функция от 1 аргумента. Единственное отличие состоит в том, что аргумент 1 сразу деструктурируется, а имена привязываются к первым двум членам. Теперь приятно понятно, как [53 32]
соответствует [lat lon]
.
Вы передаете один аргумент - вектор с двумя числами в нем.