我一直坚信,简单为美,如果一个概念不能够用数学或者简单的形式描述,那么其可用性就不能保证。
一.高阶函数
简而言之,使用函数作为参数的函数就是高阶函数。
如果在较高的层面上抽象,函数也是数据,我们可以将函数作为数据在函数之间进行传递,并在某个合适的时刻执行该函数,有时候我们也将高阶函数叫做回调函数(callback)或者钩子函数(hook),这也体现在任何一种将函数作为数据看待的语言中,如Python,JavaScript等。
在CommonLisp中我们通过defun宏定义一个函数,代码如下:
#!/usr/bin/env clisp
(defun foo (x y)
(+ x y))
;通过函数名调用函数,为了直观我们使用print打印返回结果
(print (foo 10 10))
;使用function操作符号获取函数对象
(print (function foo))
;使用function操作符的语法糖#'获取函数对象
(print #'foo)
;使用funcall调用函数
(print (funcall #'foo 10 10))
;使用apply调用函数,需要传递一个list
(print (apply #'foo (list 10 10)))
1.我们可以通过函数名对函数调用
(func-name)
2.我们可以通过function操作符获取一个函数对象,或者通过function操作符的语法糖#'来获取函数对象。
(function func-name)或者 #'func-name
3.我们可以通过funcall或者apply调用一个函数
二者的区别是前者需要一个函数对象及该函数对象需要的参数进行调用,二后者需要一个函数对象与该函数对象需要参数的列表进行调用
funcall #'func-name arg1 arg2
apply #'func-name (list arg1 arg2)
二.匿名函数
很容易理解,匿名函数就是没有名字作为句柄的函数。这个概念也存在与很多语言中。
在CommonLisp中,我们使用lambda表达式创建一个匿名函数,格式如下
(lambda (parameters) body)
如下,我们创建一个匿名函数并予以调用:
(funcall #'(lambda (x y) (+ x y)) 10 10)
当然还可以简写成如下形式:
((lambda (x y) (+ x y)) 10 10)