【问题标题】:Memory representation of values in LispLisp 中值的内存表示
【发布时间】:2015-01-24 18:11:20
【问题描述】:

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

【问题讨论】:

    标签: lisp


    【解决方案1】:

    “Lisp”是一个家族语言,而不是单一语言。该家族中的许多语言(例如,Common Lisp)没有指定内部表示,而是指定结构和功能必须保留的合同。在cons的情况下,大致是等式:

    (car (cons x y)) == x
    (cdr (cons x y)) == y
    

    以及要求 cons 每次调用时都返回一个新对象。在某些 Lisps 中,cons 单元格是不可变的,因此不存在返回新对象的要求。

    当然,实际上是有实现的,而且它们确实必须存储东西,问他们如何做到这一点并不是没有道理的。一般来说,最好将 cons 单元格视为一个足够大的结构以容纳两个指针,并且可能包含一些保存其类型的信息(以便可以将其识别为 cons 单元格)。但是,实现使用的指针可能会被标记,因此如果例如前三位是一些特殊值,则“指针”可以被识别为一些原始值的编码。

    这里的重要部分是您通常不需要知道机器上的底层表示,并且在您知道的情况下(例如,如果您正在编写代码以与另一种语言(例如,C )),那么您正在寻找的答案将针对每个实现。

    【讨论】:

    • CONS 单元是大多数 Lisps 的基础,实现会做一些特殊的事情来优化它们的运行时。例如,它们通常不像表示两个元素向量那样表示。例如,通过键入对 cons 单元格的引用来避免每个 cons 单元格的标记可能很有用。在抽象级别上没有区别,但在运行时引擎级别上可能会有很大的不同。我担心 Lisp 的实现细节在这里有点离题 - 除非它们创建程序员可见的效果。
    【解决方案2】:

    第一个 LISP 没有字符串。它只有符号和缺点。 John McCarthy's paper 中略微描述了符号字母的存储方式。字母编码为 6 位,每个地址为 5 位。一个列表(称为关联列表)将这些组合在一起,因此您可以拥有超过 5 个字母符号。

    用户永远不会接触到这些结构,所以你如何去做并不重要。我在 BrainF*ck 中制作了自己的 McCarthy Lisp Zozotez,并将我的符号名称编码为 cons,其中 car 始终是 ascii 值,cdr 要么是带有字母的新缺点,要么是 NIL .

    PS:现代 Lisps 将字符作为原始类型,类似于符号。字符串是一个字符序列。 Common Lisp 使用具有特殊类型的一维数组(=vectors)来区分字符串和其他数组,并要求它们具有字符元素。与其他向量和列表一样,您不能仅将其作为值进行比较,而是使用字符串谓词或 equalequalp 来比较序列的各个部分。

    【讨论】:

    • 这个麦克查蒂是谁? Common Lisp 之类的字符串是向量而不是列表。
    • @RainerJoswig 更好?它是列表还是向量并不重要,因为我只是想指出它们是序列而不是原始对象。是的,最好学会正确地写我英雄的名字:-)
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多