В Clojure разница между функцией, функцией с кавычками и функцией с точной кавычкой - PullRequest
21 голосов
/ 18 марта 2012

В ближайшем будущем я хотел бы знать, в чем различия между тремя ниже.

(println (map + '(1 2 3) '(4 5 6))) 

(println (map '+ '(1 2 3) '(4 5 6))) 

(println (map #'+ '(1 2 3) '(4 5 6))) 

Результаты:

(5 7 9) 

(4 5 6) 

(5 7 9) 

Я не могу понять второеповедение.

Я чувствую, что первый и третий одинаковы в clojure, который представляет собой Lisp-1 и не различает оценку переменной и функции с одинаковым именем.

Это можетбыть основным вопросом, но, кажется, недостаточно информации.Пожалуйста, научите меня.

Спасибо.

1 Ответ

33 голосов
/ 18 марта 2012

Что касается третьего случая, в отличие от Common Lisp, #'+ не читается как (function +) и относится к значению символа + в пространстве имен функции, поскольку Clojure не имеет пространства имен функции.Вместо этого он читается как (var +) и относится к var, называемому +.Применение var - это то же самое, что применение значения, хранящегося в var.

Во втором случае вы неоднократно применяете символ к паре чисел.Это действительно случайно.Применение символа к карте аналогично индексированию на этой карте:

user> ('a {'a 1, 'b 2, 'c 3, '+ 4})
1
user> ('+ {'a 1, 'b 2, 'c 3, '+ 4})
4

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

user> ('+ {'a 1, 'b 2, 'c 3} 4)
4

Поскольку на каждой итерации вы применяете символ + к паре чисел, и поскольку число не является картой и, следовательно, не содержит + в качестве ключа, втораяАргумент возвращается как значение по умолчанию для неудачного совпадения.

user> ('+ 'foo 4)
4
user> ('+ {} 4)
4
user> ('+ 1 4)
4
...