“澄清至理名言”;LISP程序员知道一切的价值,而不知道任何东西的成本。”;

“澄清至理名言”;LISP程序员知道一切的价值,而不知道任何东西的成本。”;,lisp,Lisp,我一直在思考一句至理名言 LISP程序员知道所有东西的价值,而不知道任何东西的成本 我可以找到一些提示和简短的解释,但对于这句话的真正含义并没有一个清晰、深刻的解释,尤其是对于Lisp程序员而言 请您先用简单的词语解释Perlis的格言,让CS初学者理解,然后再描述格言中隐含的相关结构、操作或情况,以了解更多的技术方面,好吗,可能是代码或伪代码示例?与许多示例一样,这至少部分是为了让您思考,而不是实际上意味着任何真正具体的东西 然而,理解他在这里的意图是相当简单的。引文分为两部分 LISP程序员

我一直在思考一句至理名言

LISP程序员知道所有东西的价值,而不知道任何东西的成本

我可以找到一些提示和简短的解释,但对于这句话的真正含义并没有一个清晰、深刻的解释,尤其是对于Lisp程序员而言

请您先用简单的词语解释Perlis的格言,让CS初学者理解,然后再描述格言中隐含的相关结构、操作或情况,以了解更多的技术方面,好吗,可能是代码或伪代码示例?

与许多示例一样,这至少部分是为了让您思考,而不是实际上意味着任何真正具体的东西

然而,理解他在这里的意图是相当简单的。引文分为两部分

LISP程序员知道一切的价值

这是指与许多编程语言不同,Lisp是一种表达式语言。这意味着在Lisp中只有一种东西:表达式,它有一个值(或者在最近的Lisp中,有一些值)。例如,在CL中,我可以说:

(let ((y (setq z 3))) ...)
因为
(setq…
是一个表达式,其值是它指定的最后一个值。我也可以这样说

(setq y (let (...) ...))
因为
(let(…)…)
是一个表达式,其值(或多个值)是其主体中最后一个表单的值(或多个值),如果没有表单,则为
nil

所以Lisp程序员知道一切的价值,因为在Lisp中,一切都是有价值的表达式

与之相比,比如说,C中有一些表达式有值,也有一些语句没有值。所以我不能在C中说:

int x = if (...) ... else ...;
因为
如果(…)。。。否则…
是C语言中的语句,而不是表达式。相反,我必须使用一个特殊的条件表达式:

int x = ...? ... : ...;
等等

(然而,我可以说
intx=y=4;
:赋值是一个用C表示的表达式。)

许多语言也是如此(例如Python也有同样的东西)

我承认我不理解为什么这些语言会有这样的区别:我想,除了使语言的语法和语义更加精细之外,肯定还有其他原因

。。。但是没有任何代价

引用的这一部分指的是Lisp中的各种操作具有时间(可能是空间)复杂性,即成本,这不是常数。这主要是因为Lisp中最独特、最重要的复合数据结构(从来不是唯一的)是由conses组成的单链接列表,而获取该列表的第n个元素所需的时间与*n$成比例

刚开始的Lisp程序员,或者仅仅是那些没有认真思考的Lisp程序员,最终编写的代码速度非常慢,扩展性非常差。例如,考虑这个:

(defun terrible-sum-list (list)
  (let ((sum 0))
    (dotimes (i (length list) sum)
      (incf sum (nth i list)))))
这是列表长度的二次型,因为它会重复遍历列表以获得第n个元素。但如果列表是一个数组,那么这将是一个完全合理的方法。相反,在Lisp中,您希望编写类似这样的代码(我有意这样写,好像很多CL都不存在:这不是习惯性的CL代码!):

或者,如果您想成为真正的原始人(但使用CL的名称来表示原始性):

Lisp在编程语言中是,或者至少是不寻常的,因为它提供的操作和数据结构的成本不容易理解。将Lisp与Fortran进行比较,尤其是与当今的Fortran进行比较

当然,这句话实际上只适用于非常小或简单的程序,因为大型和复杂的程序也开始具有不明显的复杂性,这导致了这句话的另一个版本:

Fortran程序员知道一些事情的价值和一些非常小的事情的成本


(这并不是要对Fortran程序员无礼:我是Fortran程序员。)

这只是意味着,虽然每个Lisp表单都返回一个值,但Lisp程序员可能不知道它在性能方面意味着什么,并且可能会创建幼稚而缓慢的软件。函数计算一个或多个值。这些功能可能有文档记录:什么是输入,什么是输出。通常不清楚的是:一个函数或一组函数组合的性能和“复杂性”是什么。。。在过去(这句话很古老),Lisp开发人员很难在按照今天的标准(1 MB RAM,每秒100万条指令)很小的系统上编写性能良好的程序@RainerJoswig谢谢,但是,既然这句话似乎适用于任何编程语言,那么它与Lisp有什么特别的关系呢?如果您希望添加注释作为答案,我可以选择它。在许多编程语言中,并非所有构造都返回值(表达式与语句),而且性能模型更简单(无GC,更静态分配…)谢谢,非常清楚,我现在明白了。感谢您与其他语言进行比较。这很清楚。同样感谢您提供的代码示例。关于“了解一切的价值”,我想到的另一件事是:正如语句和表达式之间并没有区别一样,Lisp也并没有真正区分代码和数据。每个程序只是一个列表-一个值@Amadan:Lisp不区分源代码和数据:Lisp程序的源代码是一个列表,程序本身通常不是。我实际上指的是在文本和编译(如果编译)之间的一个级别,宏在这个级别上运行。更多源代码不是一个列表,它只是看起来像一个列表。但是当解析的时候,代码和数据都是s-exp。@Amadan:是的,这不是你需要向我解释的:我非常理解Lisp。(当然,也有LISP,其中根本没有真正的文本形式的程序:我使用
(defun sum-list (list)
  (let ((sum 0))
    (mapc (lambda (e)
            (incf sum e))
          list)
    sum))
(defun caveman-sum-list (list)
  (let ((sum 0)
        (tail list))
    (tagbody
     loop
     (if (null tail)
         (go end))
     (setq sum (+ sum (first list))
           tail (rest tail))
     (go loop)
     end)
    sum))