Подтвердить что ты не робот

Есть ли разница между синтаксисом fn и # для анонимных функций в Clojure?

Я новичок в clojure, и я видел анонимные функции, написанные как:

(fn [x] (* x x))

а также:

#(* % %)

Очевидно, что вторая более кратка. Есть ли разница? Может ли каждая анонимная функция быть представлена ​​в любом стиле? Еще один идиоматический?

В связи с этим вопросом я не смог определить, как преобразовать (fn [x] [x x]) в последний синтаксис. Я был бы признателен за указатель на документацию, которая разъясняет эту ситуацию.

4b9b3361

Ответ 1

Наиболее важными отличиями являются:

  • (fn ...) может быть вложен, #() не может
  • Вы можете лучше назвать свои параметры с помощью (fn [x y] ..) или аналогичного, вместо использования %, %2, %3 и т.д.
  • Вы можете назвать функцию с (fn ...) для рекурсивного использования, например. (fn fib [n] (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
  • Легче создавать/манипулировать кодом (fn [...] ...), поскольку #() является макросом читателя, а не регулярной формой Clojure.
  • #() более кратким. Но если это серьезное соображение, вы, вероятно, ошибаетесь в своих приоритетах: -)

Лично мой совет:

  • Предпочитает (fn [...] ...) в большинстве случаев
  • Используйте #() только для очень коротких встроенных функций, например. (map #(+ 2 %) (range 10))
  • Также подумайте, что лучше генерировать анонимные функции через функции более высокого порядка, а не записывать их явно, например. (comp func1 func2) или (partial func param1 param2) и т.д.

Ответ 3

Из docs, я думаю, что это наиболее важные отличия:

используется идиоматика для очень короткого однократного отображения/фильтра fns и т.п.

#() формы не могут быть вложенными.

Другое дело, что если вам нужны именованные параметры, fn - лучший вариант. Для #() вы будете использовать% или, для более одного параметра, что-то вроде% 1,% 2 и т.д. (Также% &).