如何在Common Lisp中设置函数

如何在Common Lisp中设置函数,lisp,common-lisp,Lisp,Common Lisp,在Common Lisp中,我可以使用#“语法传递函数,如下所示: (let ((x #'+)) (funcall x 1 2)) (flet* ((x #'+) (y #'*)) (pprint (x 1 2)) (pprint (y 3 4)) (pprint (x (y 2 3) 4))) 但是假设我想设置一个函数,这样我就不必为它使用funcall。Common Lisp是否有一个本地函数名表,或者仅仅是通过defun分配给

在Common Lisp中,我可以使用
#“
语法传递函数,如下所示:

(let ((x #'+))
 (funcall x 1 2))
(flet* ((x #'+)
        (y #'*))
       (pprint (x 1 2))
       (pprint (y 3 4))
       (pprint (x (y 2 3) 4)))
但是假设我想设置一个函数,这样我就不必为它使用
funcall
。Common Lisp是否有一个本地函数名表,或者仅仅是通过
defun
分配给的全局函数名表

除了
defun
,是否有其他方法分配给功能符号?或者更一般地说:是否有一种方法可以做类似于此非工作示例的事情:

(setf #'x #'+)
(x 1 2)

您可以使用 :

还可以使用以下命令设置符号的函数定义:

注意,绑定 当
flet
绑定。 当符号出现在“功能”位置时,“功能” 使用单元格,当它出现在“值”位置时,“值” 使用以下单元格:

(setf (symbol-function 'x) #'car)
(setf (symbol-value 'x) #'cdr)
(x '(1 . 2))
==> 1
(funcall x '(1 . 2))
==> 2
同样地

(flet ((x (o) (car o)))
  (let ((x #'cdr))
    (cons (x '(1 . 2))
          (funcall x '(1 . 2)))))
==> (1 . 2)
这是最新的


最后,请注意,这只是该语言的一个实现。

获得这种行为的一个选项是编写一个宏来实现它

(defmacro flet* (assignments &body body)
  (let ((assignments (mapcar
                      (lambda (assn)
                        (list (first assn) '(&rest args)
                              (list 'apply (second assn) 'args)))
                      assignments)))
    `(flet ,assignments ,@body)))
此宏将
flet*
转换为
flet
+
apply
,如下所示:

(let ((x #'+))
 (funcall x 1 2))
(flet* ((x #'+)
        (y #'*))
       (pprint (x 1 2))
       (pprint (y 3 4))
       (pprint (x (y 2 3) 4)))
变成:

(flet ((x (&rest args) (apply #'+ args))
       (y (&rest args) (apply #'* args)))
       (pprint (x 1 2))
       (pprint (y 3 4))
       (pprint (x (y 2 3) 4)))

有什么东西像是
let
(setf(fdefinition…)
的组合吗?例如,
(let((x#'+)(x 3 4))=>7
,如原问题中所述?否,因为Common Lisp是一种语言。您可能需要scheme,但如果输入类似于
(此宏((xf))(x34))
,则可以编写一个扩展到
(flet((x(&rest args)(apply f args)))(x34))的宏来实现此行为。