了解常见Lisp中的引号

时间:2019-04-26 16:02:46

标签: common-lisp

在下面的实验中,我缩写为REPL返回错误,并添加了[num],以便在讨论中可以参考。

我对为什么调用存储在变量中的函数的尝试失败感到困惑。在我看来,语法比需要的复杂。

为什么我既不发行(f 3)也不发行(#'f 3)? 是否不允许将尖引号作为表格的第一要素? 为什么这里需要funcall

[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

[236]> (abs 3)                      ; This is fine
3

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

[239]> (funcall #'f 3)              ; seems very long winded...!
3

这是否意味着系统功能与用户定义功能的区别?

出于完整性考虑:

[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.

[241]> (funcall #'abs 3)                ; Isn't this verbose... ?
3

我还没有进入ANSI Common Lisp中的符号一章,也许对您有所帮助。

1 个答案:

答案 0 :(得分:7)

[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

以上将设置为f的变量设置为函数对象-来自名为abs的函数。

[236]> (abs 3)                      ; This is fine
3

上面调用了函数abs

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.

以上:没有名为f的函数。

-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

以上:Common Lisp仅接受符号作为函数名称,符号作为宏名称,符号作为特殊运算符或lambda表达式作为cons形式的第一个元素。 (function f)不是函数名称。

  

这是否意味着系统功能与用户定义功能的区别?

否。

[239]> (funcall #'f 3)              ; seems very long winded...!
3

上面用命名函数funcall中的函数对象调用函数ffuncall然后以3作为参数调用此函数对象。

  

似乎缠绕很长

是的。

  

为什么我既不发行(f 3)也不发行(#'f 3)?不允许将尖引号作为表格的第一要素吗?

因为f未命名函数。它命名一个变量。 #'f也不是函数名称。我们必须使用函数名称(实际上是一个符号)。

命名空间

公用Lisp(与其他Lisp方言一样)有两个用于函数和变量的命名空间。

定义变量foo

CL-USER 54 > (defvar foo 3)
FOO

定义函数foo

CL-USER 55 > (defun foo (x) (* foo 10))
FOO

我们可以使用从变量foo获得的值来调用函数foo

CL-USER 56 > (foo foo)
30

如何从函数的全局名称获取函数对象:

CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>

CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>

与上述相同,但用一个简短的符号表示:

CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>

CL-USER 59 > (function foo)            ; works also for local functions
#<interpreted function FOO 4230008AAC>

如何从全局变量获取值:

CL-USER 60 > (symbol-value 'foo)
3

或者只使用变量:

CL-USER 61 > foo
3

一些肯定:

正面:没有名字冲突。

我们可以写

(defun foo (list) (list list))

也不必写

(defun foo (lst) (list lst))

正面:更简单的编译

(let ((list 3))
  (list 1 list 3))

以上在Common Lisp中永远不会是错误。在Scheme中,这将是错误:3 is not a function