lisp如何决定是评估列表还是将其用作数据?
如果编写类似于lisp如何决定是评估列表还是将其用作数据?,lisp,elisp,Lisp,Elisp,如果编写类似于(+23),则+将被视为一个函数,如果+没有任何与之关联的函数定义,则会发生错误 如果您编写类似于(let(abc)),则(abc)将被读取为数据 lisp是如何决定的?这里有两个基本的lisp概念需要理解: 阅读与评价的区别 特殊形式 象征 读。评价 阅读是将文本转换为lisp对象的行为。Lisp对象(如数字和列表)具有所谓的读取形式,即可以读入对象的文本表示形式。它通常与打印表单相同。如果您来自Java之类的语言,则toString()提供对象的打印形式。没有等效的阅读概念,因
(+23)
,则+
将被视为一个函数,如果+
没有任何与之关联的函数定义,则会发生错误
如果您编写类似于(let(abc))
,则(abc)
将被读取为数据
lisp是如何决定的?这里有两个基本的lisp概念需要理解:
161
在REPL中运行时,结果如下:
161
这里发生的情况如下:
161
abc
的文本。符号的计算结果取决于它们所持有的变量。让我们在REPL中运行程序abc
:
abc
该程序实际上会产生以下错误:
eval-last-sexp-1:作为变量的符号值无效:abc
这里发生的是:
setq
将符号设置为指向变量。下面将详细介绍
特殊形式
从这里开始,Lisp就像大多数语言一样工作。调用(+1(+23))
将执行与带有plus函数的命令式语言中的plus(1,plus(2,3))
相同的操作。整个表达式将为红色,以构建列表对象(+1(+23))
,它是一个由三个元素组成的列表+
,1
和列表(+23)
。然后,作为一个函数调用的外部+
,将导致解释器计算对象1
,这是自评估,以及(+23)
,最终计算为5。然后,+
将获取两个评估对象,1
和5
,并添加它们,然后返回6
然而,Lisp有所谓的特殊形式。特殊表单可能会跳过求值步骤,只使用原始对象。例如,setq
是一种特殊形式,用于计算第二个参数,而不是第一个参数
(setq a (+ 2 3))
不会计算符号“a”,但会将符号“a”分配给(+23)
计算的对象,即数字5。然后,打电话
a
在REPL中,将打印5
所以要回答最初的问题。。。“let”是一种特殊形式,因此不会立即计算其参数:)
宏
宏也不会评估它们的参数,但可能不需要对原始问题进行充分讨论
如果您编写类似(let(abc)),则(abc)将作为数据读取
不是真的。一切都是一样的。首先读取Lisp表单。充分地评估时间较晚。评价起作用
LET
表达式是一种特殊形式,该形式根据特殊规则求值
请参阅Emacs Lisp手册:
口齿不清
- 函数调用类似于
(*ab)
- 特殊形式如
。这些表单通常是内置的,用户无法扩展(let((a 1))a)
- 宏表单类似于
(defun foo()nil)
- 再加上Lisp方言的其他功能
标识符是列表中的第一个元素,它告诉我们如何计算表单。Lisp宏也(并且必须)不计算其参数。结果是,如果您还不知道某个给定调用是否会计算其参数,则无法通过查看该调用的代码来判断。也就是说,在大多数情况下,您可以从上下文中进行很好的猜测。将读取、计算+的参数,然后将其馈送到+,。没有交叉阅读。在求值之前已读取完整表达式。似乎,
让
也立即求值,根据。正如所说,符号本身的初始值为零。