当您在 emacs lisp 中执行函数调用(myfunction ...
) 时,如果在编译时不知道该函数被定义,字节编译器将发出警告。这对自上而下的编程风格有很大帮助,从那时起我就可以愉快地编写
(defun foo (bar baz)
(foo-filter-by-functon (lambda (a b) (equal (upcase a) (upcase b)))
(foo-combine-values bar baz)))
当我编译字节编译器告诉我我还没有定义或拼错这两个foo-
函数。
但是,如果 lambda 表达式变得复杂,则需要进行更多的重构,例如
(defun foo (bar baz)
(foo-filter-by-functon 'foo-equal
(foo-combine-values bar baz)))
但是现在有一个问题...'foo-equal
现在是一个符号,并且仅在运行时执行foo-filter-by-function
检查是否'foo-equal
已定义时才会执行。通常是编译时警告的东西突然变成了运行时错误。同样的问题也适用于内置的高阶函数,例如mapcar
, apply
...
是否有可能使字节编译器识别,例如第一个参数mapcar
应该是一个函数,因此,当参数作为符号给出时,检查该符号是否具有有效的函数定义,就像它与显式(foo-equal ..)
调用一样?
注意:目的是让生产代码更具可读性,因此需要更改每次调用foo-filter-by-function
或定义中的骇客代码的解决方案是不可接受的解决方案。这种适得其反的解决方案的一个例子是
(defun foo (bar baz)
(foo-filter-by-functon (lambda (a b) (foo-equal a b)) ... )
(foo-combine-values bar baz)))
或者
(defun foo (bar baz)
(foo-filter-by-functon foo-equal
(foo-combine-values bar baz)))
(defconst foo-equal (lambda (a b) ...)
因为至少在主观上两者都会导致较差的代码可读性。