add-hook和lambda ?

请原谅我又提这种愚蠢问题,不过我实在没搞明白…… 为什么某些FUNCTION参数必须套一个lambda ? 以下代码均摘自purcell/emacs.d:

(add-hook 'after-init-hook
          (lambda () (when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame))))
(when (maybe-require-package 'company-anaconda)
    (after-load 'company
      (add-hook 'python-mode-hook
                (lambda () (sanityinc/local-push-company-backend 'company-anaconda)))))

sanityinc/local-push-company-backend:

(defun sanityinc/local-push-company-backend (backend)
    "Add BACKEND to a buffer-local version of `company-backends'."
    (make-local-variable 'company-backends)
    (push backend company-backends))

所以我现在看了几遍add-hook的文档也没看明白……到底FUNCTION在什么情况下需要套一个lambda?

谢谢各位。

1 个赞

不用 lambda,那你想怎麼写?call-by-return-value 不是很正常的逻辑嘛。

Lambda 表达式就是函数,自然能放在需要函数参数的位置上。


(elisp) Lambda Expressions

add-hook里没地方放函数的arguments把,如果要带着arguments call的话就只能用lambda

你既然知道了add-hook需要一个函数作为参数,那么

(when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame))

这两句是个函数么?不是的话自然啊要一个lambda套起来作为一个匿名函数传进去l哦

所以这两句是啥?我到现在也没弄清楚emacs-lisp里“函数”的概念……

另外sanityinc/local-push-company-backend是一个函数……

所以说函数+arguments ≠ 函数?

好吧我傻了……

FUNCTION那儿要的是个function,而不是S-expression啊……

lambda 是匿名函数呀。。。。

我知道lambda是匿名函数,我当时无法理解(其实现在也没理解)的是

为什么(add-hook 'after-init-hook 'linux-mode)linum-mode就不用lambda套,而我问题的那俩例子不套lambda就报错……

因为 linum-mode 是一个函数的名字,是有名函数

也就是说还是我对「函数」的定义理解有误?

(function 'arguments)

这已经不是「函数」了。而是「S-表达式」了

这样理解对吗?

函数和函数的名字是两码事,这个你要区分开来, 函数是一种 object, 而函数的名字是另外一种 object,我们叫他 symbol

function 的功能就是 从一个函数名字返回它对应的函数对象。

这个打个比方就是: 指针本身和指针所指的内容两者的区别

我的那个 "function“是例子,并不是要说function这个函数……

那么形如(sanityinc/local-push-company-backend 'company-anaconda)这样的东西到底是啥?

以及add-hook的FUNCTION那里要填函数名?……我越来越糊涂了……

这样说可不可以。

@ReimuXMX 你要根据返回值来看。add-hook 要的参数是函数的名字。

通常来说参数应该是 #'foo,返回函数 foo 的名字。但是为了方便,Emacs Lisp 的 #'foo 在大多数时候和 'foo 是等价的。

在 Emacs Lisp 中对于匿名函数 (lambda () (foo)) 返回的就是它的名字, (lambda () (foo)),正规的写法是 #'(lambda () (foo)),但是因为 Lisp 做了简化,所以直接写前者就可以了。

3 个赞

所以我还是不明白…

(函数 ‘参数)

这样的东西到底是个啥?

============update========= 也就是说,如果我不套lambda,那么:

(add-hook 'after-init-hook '(+ 1 2))

add-hook得到的FUNCTION就变成了(+ 1 2),(+ 1 2)不是函数名,于是就报错了?

是的。看來你有點明白了

想来你也是个初学者
那么,现在可以粗略认为,函数有两种形式,一种就是defun,一种就是lambda

(defun init|frame()
    (when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame)))

这是一个叫做init|frame的函数,可以这么用

(add-hook 'after-init-hook 'init|frame)

然后你觉得把这么一个函数就这么一个地方有用,命名空间里多出init|frame这么一个函数没多大用,那你就用个匿名函数来代替它,所以

(lambda () 
    (when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame)))

这么一坨东西也是个函数,只不过这货没有名字,没办法通过某个名字使用它,所以就只能如此

(add-hook 'after-init-hook
          (lambda () (when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame))))

对于(foo bar),可以认为这是用bar作为参数,调用了foo这个函数,所以这是个sexp,根本就不是函数

这一点你錯了,或者是说的不好,匿名函数

(lambda () 
    (when sanityinc/initial-frame
                  (run-after-make-frame-hooks sanityinc/initial-frame)))

「名字」,名字就是 (lambda () (when sanityinc/initial-frame (run-after-make-frame-hooks sanityinc/initial-frame)))

1 个赞