首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我是否遗漏了一些关于在LISP中使用符号的重要事实?

我是否遗漏了一些关于在LISP中使用符号的重要事实?
EN

Stack Overflow用户
提问于 2011-04-13 01:09:24
回答 3查看 404关注 0票数 2

简而言之。这是我在clisp中实习生和使用符号的几次尝试。

代码语言:javascript
复制
 [1]> (setq sym (intern "foo"))
 |foo|
 [2]> (eq sym 'foo)
 NIL

为什么?

代码语言:javascript
复制
 [3]> (defun internup (me &optional (package *package*))
   (intern (string-upcase me) package))
 INTERNUP

 [4]> (eq 'abc (internup "abc"))
 T

可能是大写字母。

代码语言:javascript
复制
 [12]>(let ((abc 2))
   (eval '(+ 2 abc)))

 *** - EVAL: variable ABC has no value
 The following restarts are available:

好的

代码语言:javascript
复制
 [18]> (let ((abc 2))
 (eval '(+ 2 'abc)))

 *** - +: ABC is not a number
 The following restarts are available:

有意思的。我是不是应该先设置一下。

代码语言:javascript
复制
 [14]> (setq a (internup "abc"))
 ABC

 [15]> (let ((abc 2))
 (eval '(+ 2 a)))

 *** - +: ABC is not a number
 The following restarts are available:

再一次错了。嗯,我一定是遗漏了一些关于在LISP中实战符号的重要事实。你能帮我吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-13 01:27:18

你的问题和实习无关。

第一个问题实际上是因为阅读器总是将符号大写,所以你需要调用(intern "FOO")以获得与'foo‘相同的结果。

EVAL的问题是因为LET引入了一个在EVAL中不可见的词法绑定。如果你真的想让它工作,你必须声明abc是特殊的,如下所示:

代码语言:javascript
复制
(let ((abc 2))
    (declare (special abc))
    (eval '(1+ abc)))

特殊声明将使变量具有动态绑定,而不是词法绑定(后者意味着绑定仅限于本地词法上下文,即在LET形式中。通过特殊声明,该变量可用于从该表单调用的任何内容)。

请注意,同时使用特殊声明和eval是您应该非常小心的事情,并且您可能应该从一开始就重新考虑使用EVAL。你真正需要使用它的情况非常罕见。在大多数情况下,您实际上是在寻找lambda函数的使用。

票数 3
EN

Stack Overflow用户

发布于 2011-04-13 01:26:36

Eval在null词法环境中计算表单,即没有词法绑定。这与符号的嵌入无关。

票数 3
EN

Stack Overflow用户

发布于 2011-04-13 01:45:49

Common Lisp阅读器区分大小写由可读性决定:

代码语言:javascript
复制
(readtable-case *readtable*)

通常情况下,阅读器最初会以大写形式插入符号(除非您显式转义字符)。因此:

(eq (intern "foo") 'foo) => NIL

(eq (intern "FOO") 'foo) => T

(eq (intern "FOo") 'fo\o) => T

您可以使用反引号语法为eval构建表单:

代码语言:javascript
复制
(let ((abc 2))
  (eval `(+ 2 ,abc)))

=> 4

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5639008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档