我对LISP cons单元格列表的定义正确吗? 我试图真正理解LISP,以便有一个良好的基础向前推进,但是它一直很慢,因为LISP(在我的例子中特别是普通LISP)不遵循任何C族命名约定。

我对LISP cons单元格列表的定义正确吗? 我试图真正理解LISP,以便有一个良好的基础向前推进,但是它一直很慢,因为LISP(在我的例子中特别是普通LISP)不遵循任何C族命名约定。,lisp,common-lisp,Lisp,Common Lisp,以下是我个人对LISP列表的定义,基本正确吗 LISP中的所有列表都是使用节点和下一个指针的空指针构造为单链表的 编辑:为了澄清,我用“无效指针”来表示对cons单元的CAR和CDR的性质的想法。我知道LISP中不存在“void pointer”,我在这里尝试将C的概念应用到LISP中将LISP列表视为CONS对,在CAR中有值,在CDR或nil(空列表)中有值。你可以把任何列表看作是它们的结构 e、 g.(列表1 2 3)=>(cons 1(cons 2(cons 3 nil))将Lisp列表

以下是我个人对LISP列表的定义,基本正确吗 LISP中的所有列表都是使用节点和下一个指针的空指针构造为单链表的


编辑:为了澄清,我用“无效指针”来表示对cons单元的CAR和CDR的性质的想法。我知道LISP中不存在“void pointer”,我在这里尝试将C的概念应用到LISP中

将LISP列表视为CONS对,在CAR中有值,在CDR或nil(空列表)中有值。你可以把任何列表看作是它们的结构


e、 g.
(列表1 2 3)
=>
(cons 1(cons 2(cons 3 nil))

将Lisp列表视为一个cons对,它在汽车中有值,在CDR或nil中有一个列表(空列表)。你可以把任何列表看作是它们的结构


e、 g.
(列表1 2 3)
=>
(cons 1(cons 2(cons 3 nil))

以C语言术语表示的基本Lisp数据结构可能如下所示:

[o|o]--- 2
 |
 1
[o|o]---[o|/]
 |       |
 1       2
/*值是一个“有区别的并集”*/
typedef结构值{
/*它有一个类型字段*/
枚举类型{t_cons,t_symbol,t_fixnum,t_character/*,…*/}类型;
/*然后是几个有效载荷中的一个,覆盖在同一个空间中,
根据类型字段的不同,存在哪一个*/
联合{
结构符号*sym;
结构cons*cons;
int fixnum;/*未固定整数:无堆分配*/
/* ... */
}u;
}价值观;
/*这是cons单元的堆分配部分;
不是完整的cons单元格值,它实际上是
属于“结构值”类型。见cons()
下面的函数生成一个cons值*/
结构控制{
结构价值汽车;
};
静态值nil={t_symbol};
值cons(值a、值d)
{
价值网;
struct cons*c=从特殊cons堆中分配_cons();/**/
c->car=a;
c->cdr=c;
retv.type=t_cons;
retv.u.cons=c;
返回电视;
}
int为_nil(值v)
{
返回值(v.type==t_symbol&&v.sym==NULL);
}
值cons(值a、值d)
{
结构值retv;
struct cons*c=从特殊cons堆中分配_cons();/**/
c->car=a;
c->cdr=c;
retv.type=t_cons;
retv.u.cons=c;
返回电视;
}
价值汽车(价值arg)
{
开关(参数类型){
案例t_cons:
返回参数u.cons->car;
案例t_符号:
如果(is_nil(arg))/*(car nil)->nil*/
返回零;
/*失败*/
违约:
/*此函数以某种方式生成Lisp异常*/
抛出错误(“car:不适用于~s”,arg);
}
}
Lisp概念没有详细说明数据结构

实际的Lisp实现通常会做一些更聪明的事情,以更紧凑地表示
值。一种常见的技术是使用一个机器字(现在通常是指针大小的)来表示Lisp值,并在该字中使用几个标记位来指示它是指向堆上某个对象的指针,还是整数的直接表示。(这意味着Lisp
fixnum
整数不使用所有可用的32位或64位,但可能仅使用30位或62位。较大的整数属于不同类型的
bignum
,并且是堆分配的。)

然而,对值而不是指针使用结构为浮点值创造了按值语义的机会,这对于数字代码来说是一个胜利。这意味着浮点对象不必被堆分配,而是存储在一个值中

用C编写的Lisp实现可以实现这种技巧,但它会导致ISO C未定义的行为,并且声明和代码对于说明目的来说并没有那么好

对于这种类型的表示,一个很好的细节是对Lisp符号使用C null指针
nil
。然后,任何用C编写的内部例程都可以使用与Lisp相同的约定以符合人体工程学的方式编写:
nil
既为false,又为空列表

C受Lisp的影响很大,因为它基于返回值的表达式,并且空指针是假的。c中的
a?b:c
三元运算符在某种程度上是Lisp的
(如果是abc)
的翻版


它需要相当多的C代码行来引导看起来像Lisp语义的东西,并且它的许多方面都有多种设计选择。因此,最好尝试将Lisp理解为一种抽象,而不是通过特定的详细数据结构和执行模型设计,更不用说用C语言表达的Lisp。用C语言表达的基本Lisp数据结构可能如下所示:

[o|o]--- 2
 |
 1
[o|o]---[o|/]
 |       |
 1       2
/*值是一个“有区别的并集”*/
typedef结构值{
/*它有一个类型字段*/
枚举类型{t_cons,t_symbol,t_fixnum,t_character/*,…*/}类型;
/*然后是几个有效载荷中的一个,覆盖在同一个空间中,
根据类型字段的不同,存在哪一个*/
联合{
结构符号*sym;
结构cons*cons;
int fixnum;/*未固定整数:无堆分配*/
/* ... */
}u;
}价值观;
/*这是cons单元的堆分配部分;
不是完整的cons单元格值,它实际上是
属于“结构值”类型。见cons()
下面的函数生成一个cons值*/
结构控制{
结构价值汽车;
};
静态值nil={t_symbol};
值cons(值a、值d)
{
价值网;
struct cons*c=从特殊cons堆中分配_cons();/**/
c->car=a;
c->cdr=c;
retv.type=t_cons;
retv.u.cons=c;
返回电视;
}
int为_nil(值v)
{
返回值(v.type==t_symbol&&v.sym==NULL);
}
值cons(值a、值d)
{
结构值retv;
结构cons*c=allocate_cons();/*fr
(list 1 2)
;; => (1 2)
'(1 2)
;; => (1 2)