浏览Common Lisp源我注意到人们最常使用#'foo
'foo
就足够了 - 也就是说,只要接受函数指示符,他们就会选择传递函数。
当通过#'foo
定义foo
时,{} {}}当然是必要的。我理解这一切的机制 - 我的问题是风格。是不是因为人们不想考虑flet
与'foo
,所以他们使用后者因为前者有时不起作用?即使如此,也无法解释#'foo
的使用,因为#'(lambda ...)
总是不必要。
#'
,CL有时被称为丑陋,而大多数新手并没有意识到在大多数情况下(我敢说)这是不必要的。我不是新人,但我更喜欢#'
。为什么我不寻常?如果我发布一些给'foo
和funcall
符号的代码,我会被嘲笑和羞辱吗?我正在考虑在我的区域开始一个功能标志符号匿名章节。我怀疑人们想要使用功能指示器,但由于同伴的压力,他们不敢“出来”。
答案 0 :(得分:4)
使用#'
在概念上更简单:无论是处理匿名函数,通过调用compile
获得的函数,还是使用#'
引用的函数,您总是引用一个功能对象。鉴于此,将符号传递给map
或funcall
是一个奇怪的特殊情况,它不像传递函数对象那样直观。
但是,有些情况下符号在概念上可能更合适,例如:test
make-hash-table
参数的情况。在这种情况下,您将从键比较函数的名称指定的四种不同类型的哈希表中选择一种。在这种情况下,我更喜欢符号,因为使用函数对象来区分一种哈希表与另一种哈希表没有关系。 (它也具有误导性,因为它往往会欺骗你,使你相信你可以将任意等价谓词传递给make-hash-table
。)
答案 1 :(得分:3)
他们不一样。 'foo
是对任何恰好是foo
函数的全局定义的引用,并且是当旧范围非常混淆的时候遗留下来的。
CL-USER(1): (defun foo (x) 1)
FOO
CL-USER(2): (flet ((foo (x) 2)) (mapcar #'foo '(1 2 3)))
(2 2 2)
CL-USER(3): (flet ((foo (x) 2)) (mapcar 'foo '(1 2 3)))
(1 1 1)
答案 2 :(得分:0)
这是两个独立的风格决定,任何人都必须为自己做出决定。我从未见过对这四种组合中任何一种的批评。
我个人更喜欢使用#'
代替'
,因为它使函数更加明显。我认为,这根本不是丑陋的 - 相反,我喜欢这种更明确的语法。虽然在Clojure中编程,但我很少会错过它。
然而,我使用lambda
没有尖锐的引用。可以在Let over Lambda中找到对此的良好讨论。我相信#'(lambda...
的原始论点是肯特皮特曼。