Обязательный вопрос Clojure - PullRequest
       0

Обязательный вопрос Clojure

1 голос
/ 26 сентября 2011

просто хочу пересчитать некоторый простой код

У меня есть функция

(defn foo
    ([x y]
        (let [line [x y]]
            (...))
    ([x y z]
        (let [plane [x y z]]
            (...))))

Я знаю, что могу написать

(let [[x y :as point] [1 0]])

Есть ли аналогичная деструктуратакие функции, как foo, где я могу написать [x y :as line] или [x y z :as plane] в фактическом defn?(то есть самолет будет назначен [xyz])

Ответы [ 2 ]

2 голосов
/ 26 сентября 2011

Вы всегда можете построить let с помощью макроса.Это даст вам возможность написать что-то наподобие:

(def foo
  (build-foo-args [[x y] line]
     (...))
  (build-foo-args [[x y z] plane]
     (...)))

Не уверен, что этот синтаксический сахар действительно покупает вас, хотя ... во-первых, все довольно ясно.

Вкл.В целом, я бы порекомендовал переосмыслить сигнатуру вашей функции:

  • Если вам действительно нужно различное поведение для разных арностей, то foo, вероятно, следует разделить на отдельные функции.

  • Если поведение одинаково для разных арностей, то я бы использовал переменные аргументы, как это предложил Дэйв Рэй, но назвал объединенный аргумент чем-то нейтральным, например, «нормальный вектор», который может относиться к многомерности.Вы можете обнаружить, что вам вообще не нужны имена x, y, z ...

2 голосов
/ 26 сентября 2011

Вы также можете выполнить деструктуризацию в списке аргументов, но вам придется использовать переменные аргументы, что означает, что вы не можете иметь несколько подписей:

(defn foo [& [x y z :as plane]]
  (...))

, а затем позвоните как:

(foo 1 2 3)

но, как я сказал выше, при таком подходе две и три формы arg становятся неоднозначными, поэтому вам придется иметь отдельные именованные функции.

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