Function #与#x27之间的差异;被叫人和';公共Lisp中的被调用方

Function #与#x27之间的差异;被叫人和';公共Lisp中的被调用方,function,lisp,common-lisp,Function,Lisp,Common Lisp,以下是我常用的Lisp代码: (defun caller (f) (format t "caller: f: ~a~%" f) (funcall f 10)) (defun callee (x) (format t "callee: x: ~a~%" x)) (caller #'callee) (caller 'callee) 以下是我通过clisp获得的输出: $ clisp foo.lisp caller: f: #<FUNCTION CALLEE (X) (DEC

以下是我常用的Lisp代码:

(defun caller (f)
  (format t "caller: f: ~a~%" f)
  (funcall f 10))

(defun callee (x)
  (format t "callee: x: ~a~%" x))

(caller #'callee)
(caller 'callee)
以下是我通过
clisp
获得的输出:

$ clisp foo.lisp 
caller: f: #<FUNCTION CALLEE (X) (DECLARE (IN-DEFUN CALLEE)) (BLOCK CALLEE (FORMAT T callee: x: ~a~% X))>
callee: x: 10
caller: f: CALLEE
callee: x: 10
$clisp foo.lisp
来电者:f:#
被叫人:x:10
主叫人:f:被叫人
被叫人:x:10
我想知道被调用方的语法和被调用方的语法有什么区别

虽然使用这两种语法,我能够将
被调用方
传递给
调用方
,但是
调用方:f:
输出似乎表明这两种语法之间存在一些细微的差异:
#“被调用方
似乎引用函数对象,而
被调用方
似乎只引用函数名称

以下是我的问题:

  • #“被调用方
    语法和
    被调用方
    语法之间有什么区别
  • 在这两种情况下,
    funcall
    如何能够成功调用
    被调用方
  • 由于哪一种语法优于另一种语法,这两种语法是否都有最佳实践或优缺点

  • 区别主要在于如何查找函数。如果将符号传递给
    funcall
    ,则会在全局(而不是词汇)环境中查找该符号。相关文件如下所示。我稍微修改了文档中的示例:

    (defun cons* (&rest rest)
      (apply 'cons rest))
    
    (flet ((cons* (x y) `(kons ,x ,y)))
      (let ((cons* (symbol-function '+)))
        (funcall #'cons*
             (funcall 'cons* 1 2)
             (funcall cons* 1 2))))
    
    ;; => (KONS (1 . 2) 3)
    

    区别主要在于如何查找函数。如果将符号传递给
    funcall
    ,则会在全局(而不是词汇)环境中查找该符号。相关文件如下所示。我稍微修改了文档中的示例:

    (defun cons* (&rest rest)
      (apply 'cons rest))
    
    (flet ((cons* (x y) `(kons ,x ,y)))
      (let ((cons* (symbol-function '+)))
        (funcall #'cons*
             (funcall 'cons* 1 2)
             (funcall cons* 1 2))))
    
    ;; => (KONS (1 . 2) 3)
    
    #被调用方
    扩展为
    (函数被调用方)
    ,而
    被调用方
    扩展为
    (引用被调用方)

    #'
    在函数名空间中查找。(Common Lisp是2-Lisp,这意味着它有两个独立的名称空间,允许函数具有与变量/数据相同的名称-Scheme/Racket是1-Lisp,其中函数和变量共享相同的名称空间-这意味着具有特定名称的某事物是函数或某个其他对象的名称)

    不会在任何地方查找,但会将以下符号名称计算为其自身的名称

    funcall
    在函数名称空间中查找其参数名称,并返回分配给它的函数。如果执行普通函数调用
    (被调用方10)
    ,Lisp解释器会从函数名称空间隐式查找
    被调用方
    ,因为列表中执行的第一个位置是为函数名保留的。当函数名作为参数给出时,在第一个位置以外的其他位置,您必须首先对它们应用
    funcall
    #'
    ,以便解释器知道它必须在函数名空间而不是普通变量名空间中查找此名称

    试试这个:

    (defun d (x) x) ;; declares a function d in the function name space
    (setf d 1)      ;; declares variable d in the variable name space
    (list d #'d d #'d)
    ;; returns:
    (1 #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)> 1
    #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>)
    ;; when `#'` is given, the d is looked up from the function name space,
    ;; without, d is looked up from the normal variable name space
    (d d)
    ;; the first position d gets looked up from the function name space but 
    ;; the argument d from the variable name space
    ;; since the function d is the identity function and variable d has the value 1,
    ;; this evaluates the identity function on 1, thus to
    1
    (d #'d) ;; now the argument `d` is looked up from the function name space
    ;; thereby returning a function:
    #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>
    
    (defund d(x)x);;在函数名空间中声明函数d
    (setf d 1);;在变量名称空间中声明变量d
    (列表d#'d#'d)
    ;; 返回:
    (1 # 1
    #)
    ;; 给定`#``时,从函数名空间中查找d,
    ;; 如果没有,则从普通变量名称空间查找d
    (d)
    ;; 从函数名空间查找第一个位置d,但
    ;; 参数从变量名称空间中删除
    ;; 因为函数d是恒等函数,变量d的值为1,
    ;; 这将计算1上的标识函数,从而
    1.
    (d#'d);;现在从函数名空间中查找参数'd'
    ;; 从而返回一个函数:
    #
    
    #被调用方
    扩展为
    (函数被调用方)
    ,而
    被调用方
    扩展为
    (引用被调用方)

    #'
    在函数名空间中查找。(Common Lisp是2-Lisp,这意味着它有两个独立的名称空间,允许函数具有与变量/数据相同的名称-Scheme/Racket是1-Lisp,其中函数和变量共享相同的名称空间-这意味着具有特定名称的某事物是函数或某个其他对象的名称)

    不会在任何地方查找,但会将以下符号名称计算为其自身的名称

    funcall
    在函数名称空间中查找其参数名称,并返回分配给它的函数。如果执行普通函数调用
    (被调用方10)
    ,Lisp解释器会从函数名称空间隐式查找
    被调用方
    ,因为列表中执行的第一个位置是为函数名保留的。当函数名作为参数给出时,在第一个位置以外的其他位置,您必须首先对它们应用
    funcall
    #'
    ,以便解释器知道它必须在函数名空间而不是普通变量名空间中查找此名称

    试试这个:

    (defun d (x) x) ;; declares a function d in the function name space
    (setf d 1)      ;; declares variable d in the variable name space
    (list d #'d d #'d)
    ;; returns:
    (1 #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)> 1
    #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>)
    ;; when `#'` is given, the d is looked up from the function name space,
    ;; without, d is looked up from the normal variable name space
    (d d)
    ;; the first position d gets looked up from the function name space but 
    ;; the argument d from the variable name space
    ;; since the function d is the identity function and variable d has the value 1,
    ;; this evaluates the identity function on 1, thus to
    1
    (d #'d) ;; now the argument `d` is looked up from the function name space
    ;; thereby returning a function:
    #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>
    
    (defund d(x)x);;在函数名空间中声明函数d
    (setf d 1);;在变量名称空间中声明变量d
    (列表d#'d#'d)
    ;; 返回:
    (1 # 1
    #)
    ;; 给定`#``时,从函数名空间中查找d,
    ;; 如果没有,则从普通变量名称空间查找d
    (d)
    ;; 从函数名空间查找第一个位置d,但
    ;; 参数从变量名称空间中删除
    ;; 因为函数d是恒等函数,变量d的值为1,
    ;; 这将计算1上的标识函数,从而
    1.
    (d#'d);;现在从函数名空间中查找参数'd'
    ;; 从而返回一个函数:
    #
    
    相关问题:相关问题:由于我还是Lisp的初学者,您能解释一下我的哪个示例传递符号吗?你的意思是
    #被调用方
    正在传递函数对象而
    被调用方
    正在传递符号吗?准确地说
    #'被调用方
    扩展为
    (函数被调用方)
    ,而
    被调用方
    是lisp符号。在线图书:是一个伟大的介绍