Как мне сделать литеральную функцию, которая не принимает аргументы и возвращает постоянное значение?

Я пытаюсь изучить Clojure и застрял в буквальном синтаксисе функций. Я не могу понять, что такое буквальный эквивалент функции (defn fourteen [] 14).

(def fourteen (fn [] 14))
;; => #'user/fourteen
(fourteen)
;; => 14
(defn defn-fourteen [] 14)
;; => #'user/defn-fourteen
(defn-fourteen)
;; => 14
(def literal-14 #(14))
;; => #'user/literal-14
(literal-14)
;; ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn  user/literal-14 (form-init2956929406616221071.clj:1)

Я не думаю, что это дубликат сколько аргументы ожидает ли анонимная функция в clojure?, но, возможно, это так, и у меня просто нет опыта, чтобы распознать это.

Как или можно определить литерал-14, чтобы вызов (literal-14) работал?


person Bob Kuhar    schedule 02.03.2016    source источник


Ответы (2)


14 не является функцией, но do или -> в крайнем случае подойдет:

#(do 14)
#(-> 14)
person Sean    schedule 02.03.2016
comment
#(do 14) работает, #(identity 14), возможно, немного понятнее, и, конечно, (constantly 14) правильно - person A. Webb; 02.03.2016
comment
Итак, первая «вещь» внутри функционального литерала должна быть функцией? Я не совсем понимаю, но и вариант do, и варианты идентичности делают то, что я ищу, но я все еще немного не понимаю, что такое литерал анонимной функции. - person Bob Kuhar; 02.03.2016
comment
@BobKuhar Попробуйте (macroexpand '#(14)) и т. д. - person A. Webb; 02.03.2016
comment
@A.Webb (macroexpand '#(14)) приводит к (fn* [] (14)), что ясно показывает аспект списка, о котором говорит @Elogent. Но теперь сама fn* — это новый вопрос. Это другой фн? Что * там делает? Я не могу получить документ на него. Я крыса в лабиринте! Но спасибо за помощь. Может быть, облака рассеются. - person Bob Kuhar; 02.03.2016
comment
@BobKuhar fn* — это специальная форма, поверх которой строится макрос fn. Для простых случаев, подобных этому, они эквивалентны. - person Sam Estep; 02.03.2016

Как А. Уэбб указал, constantly — самый идиоматический способ написать это:

(def fourteen (constantly 14))

Проблема с литералом анонимной функции заключается в том, что он всегда расширяется до функции, телом которой является список:

'#(stuff and things) ;=> (fn* [] (stuff and things))

Итак, вот что происходит в вашей попытке:

'#(14) ;=> (fn* [] (14))

Избавиться от этих скобок невозможно. Вы можете обойти их, используя do или identity или что-то в этом роде, но суть в том, что если вам нужно написать анонимную функцию, тело которой не подходит для записи в виде списка, вы не должны использовать литерал синтаксис.

person Sam Estep    schedule 02.03.2016