Lisp中值的内存表示

Lisp中值的内存表示,lisp,Lisp,我读到在原始的lisp中,CONS在内存中以36位表示,前18位表示CAR(15位表示地址,3位表示它是ATOM的地址还是另一个CONS),后18位表示CDR(15位…)。我的问题是,如果原子需要超过一个字节,例如字符串,那么它的表示形式是什么?“Lisp”是一个语言家族,而不是一种单一的语言。族中的许多语言(例如Common Lisp)没有指定内部表示,而是指定结构和函数必须保留的契约。在cons的情况下,大致如下所示: (car (cons x y)) == x (cdr (cons x y

我读到在原始的lisp中,CONS在内存中以36位表示,前18位表示CAR(15位表示地址,3位表示它是ATOM的地址还是另一个CONS),后18位表示CDR(15位…)。我的问题是,如果原子需要超过一个字节,例如字符串,那么它的表示形式是什么?

“Lisp”是一个语言家族,而不是一种单一的语言。族中的许多语言(例如Common Lisp)没有指定内部表示,而是指定结构和函数必须保留的契约。在cons的情况下,大致如下所示:

(car (cons x y)) == x
(cdr (cons x y)) == y
每次调用时,cons返回一个新对象的要求。在某些Lisp中,cons单元格是不可变的,因此不存在返回新对象的要求

当然,实际上是有实现的,它们确实需要存储东西,问它们是如何实现的并不是不合理的。一般来说,最好将cons单元格视为一个足够大的结构,可以容纳两个指针,可能还有一些信息可以容纳其类型(因此可以将其识别为cons单元格)。不过,实现所使用的指针可能会被标记,因此,例如,如果前三位是一些特殊值,“指针”可以被识别为一些原语值的编码


这里重要的一点是,您通常不需要知道机器上的底层表示,而且在您知道的情况下(例如,如果您正在编写代码以与另一种语言(例如,C)进行接口),然后,您要寻找的答案将特定于每个实现。

第一个LISP没有字符串。它只有象征和缺点。符号字母的存储方式在本手册中略作描述。字母编码为6位,每个地址可容纳5个字母。一个列表(称为关联列表)将这些符号放在一起,这样您就可以有5个以上的字母符号

用户从未接触过这些结构,因此如何接触并不重要。我在BrainF*ck中制作了自己的麦卡锡Lisp,并将我的符号名称编码为
cons
,其中
car
始终是ascii值,
cdr
要么是带字母的新cons,要么是
NIL


现代Lisp将字符作为基本类型,类似于符号。字符串是一个字符序列。公共Lisp使用具有特殊类型的一维数组(=向量)来区分字符串和其他数组,并要求这些数组具有字符元素。与其他向量和列表一样,您不能仅将其作为值进行比较,而是使用字符串谓词或将比较序列各部分的
equal
equalp

最常见的是,引用符号的cons单元格仅包含指向描述该符号的某些结构的指针。因此,EQ可以实现为指针比较。这三个额外的位用于保存一些类型信息,这样即使是fixnum也可以通过这种方式进行编码和比较。

CONS单元格是大多数LISP的基本单元,它们的实现会做一些特殊的事情来优化它们的运行时。例如,它们通常不像表示两个元素向量那样表示。例如,通过键入对cons单元格的引用,可以避免每个cons单元格的标记。它在抽象级别上没有区别,但在运行时引擎级别上可能有很大的区别。我担心Lisp的实现细节在这里有点离题——除非它们能产生程序员可见的效果。这个McCharty是谁?类似于Common Lisp的字符串是向量而不是列表。@RainerJoswig更好吗?不管是列表还是向量,因为我只想指出它们是序列而不是原始对象。是的,最好学着写我英雄的名字,对吗:-)