高阶函数中的Clojure算子

高阶函数中的Clojure算子,clojure,Clojure,我把一个高阶函数放在一起,在某些情况下调用函数参数,但根据函数的不同,它似乎有不同的效果。我能够通过一个简单的函数重现相同的行为: defn foo[f a b]f a b 对于正常功能,它可以正常工作: 用户=>foo列表2 3 2 3 用户=>foo cons 1'2 3 1 2 3 用户=>foo println 2 3 2 3 无 但对于操作符来说,它并没有,它似乎只是返回最后一个元素: user=> (foo '+ 2 3) 3 user=> (foo '* 2 3) 3

我把一个高阶函数放在一起,在某些情况下调用函数参数,但根据函数的不同,它似乎有不同的效果。我能够通过一个简单的函数重现相同的行为:

defn foo[f a b]f a b 对于正常功能,它可以正常工作:

用户=>foo列表2 3 2 3 用户=>foo cons 1'2 3 1 2 3 用户=>foo println 2 3 2 3 无 但对于操作符来说,它并没有,它似乎只是返回最后一个元素:

user=> (foo '+ 2 3)
3
user=> (foo '* 2 3)
3
user=> (foo '- 2 3)
3

为什么会出现这种情况?

在clojure中,像+这样的运算符只是普通函数。不要使用单一的报价,它会很好的工作

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(defn foo [f a b] (f a b))

(dotest
  (spyx (foo list 2 3))
  (spyx (foo println 2 3))
  (spyx (foo + 2 3))
  (spyx (foo * 2 3))
  (spyx (foo - 2 3)) )
结果如下:

(foo list 2 3) => (2 3)

2 3                        ; result of (println 2 3)
(foo println 2 3) => nil   ; println always returns `nil`

(foo + 2 3) => 5
(foo * 2 3) => 6
(foo - 2 3) => -1
辅助函数spyx只打印一个表达式,然后打印它的值

user=> (foo '+ 2 3)
3
为什么会这样

'或quote在需要+函数值时创建+符号:

因此,总是返回第二个参数的行为来自这样一个事实,即关键字等符号也充当函数,通常用作获取关联结构(如地图)的简写,因此它们在功能上是等效的:

('foo 1 2) => 2
(get 1 'foo 2) => 2
当在关联结构中找不到键时,2正好位于用于默认值的位置

如果您有一个带有符号键的地图,这将非常有用,就像关键字一样:

('foo {'foo 1}) => 1
({'foo 1} 'foo) => 1
('foo {'bar 1} 2) => 2

正如一个有趣的事实,为什么它似乎只是返回最后一个元素,请看第二个参数是默认值,它默认为。我不知道您为什么需要这样做,但它允许您执行类似于“+{'+2}返回2”的操作。@Carcigenicate的原因当然与您希望对关键字执行该操作的原因相同。有时候,不管出于什么原因,你可能只需要一个由符号键入的映射,例如,在实现解释器时的词法环境,想要能够使用符号作为函数来查找自己并不疯狂。@amalloy确实如此。我只是觉得我从来没有必要做这样的查找。疯了!我从没听说过这个。我会认为这是一个噱头,而不是一个特征。
('foo {'foo 1}) => 1
({'foo 1} 'foo) => 1
('foo {'bar 1} 2) => 2