1) 变量的新概念。在Lisp中,所有变量都是指针。值有类型,而不是变量,分配或绑定变量意味着复制指针,而不是它们所指向的内容。
(defun print-twice (it)
(print it)
(print it))
'it' 是一个变量。它可以绑定到任何值,没有限制和类型与变量相关联。如果调用函数,不需要复制参数。变量类似于指针,有一种方法可以访问绑定到变量的值,并且无需保留内存。我们在调用函数时可以传递任何数据对象:任何大小和任何类型。
数据对象具有“类型”,所有数据对象都可以查询其“类型”。
(type-of "abc") -> STRING
2) 符号类型。与字符串不同的是,你可以通过比较指针来测试相等性。
符号是带有名称的数据对象。通常可以使用名称来查找对象:
|This is a Symbol|
this-is-also-a-symbol
(find-symbol "SIN") -> SIN
由于符号是实际的数据对象,我们可以测试它们是否为同一对象:
(eq 'sin 'cos) -> NIL
(eq 'sin 'sin) -> T
这使我们可以使用符号来编写句子,例如:
(defvar *sentence* '(mary called tom to tell him the price of the book))
现在我们可以统计句子中“THE”的数量:
(count 'the *sentence*) -> 2
在Common Lisp中,符号不仅有名称,还可以具有一个值、一个函数、一个属性列表和一个包。因此,符号可用于命名变量或函数。属性列表通常用于向符号添加元数据。
3)使用符号树的代码表示方法。
Lisp使用其基本数据结构来表示代码。
列表(* 3 2)既可以是数据也可以是代码:
(eval '(* 3 (+ 2 5))) -> 21
(length '
树:
CL-USER 8 > (sdraw '(* 3 (+ 2 5)))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
* 3 [*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
+ 2 5
4) 整个语言始终可用。读取时间、编译时间和运行时间之间没有真正的区别。您可以在阅读时编译或运行代码,编译时阅读或运行代码以及运行时阅读或编译代码。
Lisp提供了READ函数从文本中读取数据和代码,LOAD函数加载代码,EVAL函数评估代码,COMPILE函数编译代码和PRINT函数将数据和代码写入文本。
这些函数始终可用。它们不会消失。它们可以成为任何程序的一部分。这意味着任何程序都可以始终读取、加载、评估或打印代码。
在像C或Java这样的语言中,它们有何不同之处?
这些语言不提供符号、代码作为数据或数据作为代码的运行时评估。C中的数据对象通常是无类型的。
除了LISP家族语言之外,还有其他语言现在具有这些结构吗?
许多语言具有其中一些能力。
区别:
在Lisp中,这些能力被设计成易于使用的语言特性。