Как объединить явные аргументы с переменными аргументами в вызове функции - PullRequest
1 голос
/ 22 апреля 2019

В JavaScript можно сделать следующее:

function foo(arg1, arg2, arg3) {
  ...
}

var others = [ 'two', 'three' ];
foo('one', ...others);  // same as foo('one', 'two', 'three')

В Clojure «переменные аргументы» могут быть приняты следующим образом:

(defn foo [arg1 & others]
  ...)

Но чтобы передать их в сочетании с другими аргументами, вы должны сделать это:

(apply foo (concat '("one") others))

Что, честно говоря, действительно безобразно. Также невозможно, когда то, что вам нужно сделать, это повторить:

(apply recur (concat '("one") others)) ;; doesn't work

Есть ли лучший способ сделать это? А если нет, то есть ли способ сделать это в случае recur?

1 Ответ

5 голосов
/ 22 апреля 2019

Но чтобы передать их в сочетании с другими аргументами, вы должны сделать это: (apply foo (concat '("one") others))

У вас нет для этого: apply также является переменной функцией, которая может принимать аргументы перед последним аргументом последовательности, например,

(apply foo "one" others)

Вы можете передать любое количество отдельных аргументов перед последним аргументом последовательности в apply.

user=> (defn foo [arg1 & args] (apply println arg1 args))
#'user/foo
user=> (apply foo "one" 2 "three" [4 "five" 6.0])
one 2 three 4 five 6.0

Для дальнейшей демонстрации эти вызовы + функционально эквивалентны:

(apply + 1 2 [3])
(apply + 1 [2 3])
(apply + [1 2 3])

Это также невозможно, когда вам нужно повторить

recur - это специальная форма , и apply не работает с ней, как с обычной функцией Clojure.

есть ли способ сделать это в случае recur?

Не с apply. Вы можете recur с переменными аргументами, но вы не можете (apply recur ...).

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