Common Lisp中的高阶函数语法

vru*_*e21 4 lisp common-lisp

我正在使用Norvig的人工智能编程范式教自己Common Lisp,并且遇到了一些我不理解的东西,他没有解释.

(defun mappend (fn the-list)
  (apply #'append (mapcar fn the-list)))
Run Code Online (Sandbox Code Playgroud)

如下调用高阶函数higherOrderFunc #'funcName funcArg和在mapcar没有调用时执行的操作有什么区别#'?是#'调用高阶函数时,有必要吗?

Rai*_*wig 8

Common Lisp具有不同的函数和变量名称空间.

(defun mappend (fn the-list)
   (apply #'append (mapcar fn the-list)))
Run Code Online (Sandbox Code Playgroud)

上面MAPPEND的定义有两个局部变量fnthe-list

APPLY获取传递的函数APPEND.

MAPCAR得到传递的变量FN.

类似的看到这个:

CL-USER 129 >  (flet ((add-something (number)
                       (+ number 17)))
                (let ((add-something (lambda (number)
                                       (+ number 42))))
                  (list
                   (mapcar #'add-something '(1 2 3))
                   (mapcar add-something '(1 2 3)))))

->

((18 19 20) (43 44 45))
Run Code Online (Sandbox Code Playgroud)

LET创建局部变量,FLET创建局部函数.

第一个mapcar使用函数名称空间,第二个使用变量名称空间.

Common Lisp使用特殊的函数命名空间,因为它被认为更有效(稍微更容易实现快速Lisp)并允许函数和变量具有相同的名称.

在Common Lisp中我们可以写:

(defun list-me (list)
  (list list))
Run Code Online (Sandbox Code Playgroud)

在Scheme中,没有单独的命名空间,可以写这样的东西:

(define (list-me lst)
  (list lst))
Run Code Online (Sandbox Code Playgroud)


Sva*_*nte 6

#'是语法糖function:#'foo读为(function foo).

Function是一个特殊的运算符,它返回绑定到给定名称的函数值.如果将函数作为参数传递,则该参数(在您的情况下fn)将其值绑定到函数.要将其传递给另一个函数,您只需将变量名称放入调用表单即可.但是,要获取名称的函数值,您需要使用它来访问它function.