我怎么'得到'Lisp?

xof*_*ofz 22 lisp

我读过Lisp的本质.我唯一能做到的就是"代码就是数据".但是,如果没有定义这些术语的含义以及为什么它们通常被认为是分开的,我就没有得到任何见解.我对"代码就是数据"的最初反应是什么呢?

Rai*_*wig 55

旧式的观点:'它'是具有符号表达的交互式计算.

Lisp可以轻松表示各种表达式:

英语句子

(the man saw the moon)
Run Code Online (Sandbox Code Playgroud)

数学

(2 * x ** 3 + 4 * x ** 2 - 3 * x + 3)
Run Code Online (Sandbox Code Playgroud)

规则

(<- (likes Kim ?x) (likes ?x Lee) (likes ?x Kim))
Run Code Online (Sandbox Code Playgroud)

还有Lisp本身

(mapcar (function sqr) (quote (1 2 3 4 5)))
Run Code Online (Sandbox Code Playgroud)

还有很多很多.

Lisp现在允许编写使用这些表达式计算的程序:

(translate (quote (the man saw the moon)) (quote german))

(solve (quote (2 * x ** 3 + 4 * x ** 2 - 3 * x + 3)) (quote (x . 3)))

(show-all (quote (<- (likes Kim ?x) (likes ?x Lee) (likes ?x Kim))))

(eval (quote (mapcar (function sqr) (quote (1 2 3 4 5)))))
Run Code Online (Sandbox Code Playgroud)

交互式意味着编程是与Lisp的对话.您输入一个表达式,Lisp计算副作用(例如输出)和值.

因此,您的编程会话就像与Lisp系统"交谈".你可以使用它,直到你得到正确的答案.

这些表达是什么?他们是某种语言的句子.它们是涡轮机的部分描述.它们是描述AMD处理器的浮点引擎的定理.它们是物理学中的计算机代数表达式.它们是电路的描述.它们是游戏中的规则.它们描述了游戏中演员的行为.它们是医疗诊断系统中的规则.

Lisp允许您将事实,规则,公式写下来作为符号表达式.它允许您编写使用这些表达式的程序.您可以计算公式的值.但是你可以同样轻松地编写从公式计算新公式的程序(符号数学:集成,派生,......).这是Lisp的设计目标.

作为副作用,Lisp程序也表示为这样的表达式.然后还有一个Lisp程序,用于评估或编译其他Lisp程序.所以Lisp的概念,即带有符号表达式的计算,已经应用于Lisp本身.Lisp程序是符号表达式,计算是Lisp表达式.

Alan Kay(Smalltalk成名)将Lisp评估的原始定义称为Maxwell的编程方程.

  • 你的帖子继续令我惊讶.你有很好的能力将Lisp基础知识传达给新手. (12认同)

Pau*_*ier 35

编写Lisp代码.真正"获得"Lisp(或任何语言,就此而言)的唯一方法就是卷起袖子并实现其中的一些东西.像其他任何东西一样,你可以阅读你想要的所有东西,但是如果你想真正掌握正在发生的事情,你必须走出理论并开始实践.

  • 确实.模式被称为模式,因为它们自己出现,它们没有规定.开始编码; 如果事情感觉良好,你可能做得对.如果事情感觉不好,你可能做错了(或使用PHP). (10认同)
  • 实际上,使用Lisp语法编写C代码是第一步.没有人会改变语言并立即掌握新的范例 - 你必须先学会理解你所看到的基本结构,然后你就可以专注于解决更精细的细节和全新的概念.但是在你用语言编写一些代码之前,学习所有的构造并没有多大帮助. (9认同)
  • 是的,写作很好,但如果它只是试图用Lisp语法编写C代码,那就没有多大好处. (4认同)
  • 是的,如果你只知道C,那么在Lisp中编写C代码并不一定是坏事.实际上,它比抓取一些通用的"列表和递​​归"文本更好,这些文本几乎不适合开发人员想要做的事情.选择一个应用程序,然后根据需要编写它.当你完成后,如果你愿意的话,你可以回来再写一遍,让它变得"更加lispy".总是更容易学习将语言应用到您认识的域名的语言. (3认同)

jal*_*alf 24

你"获得"任何语言的方式是尝试在其中编写一些代码.

关于"数据是代码"的事情,在大多数语言中,执行的代码与处理的数据之间存在明显的分离.

例如,以下简单的类C函数:

void foo(int i){
  int j;

  if (i % 42 == 0){
    bar(i-2);
  }

  for (j = 0; j < i; ++j){
    baz();
  }
}
Run Code Online (Sandbox Code Playgroud)

实际控制流程在编写代码时静态确定一次.该函数bar不会改变,函数开头的if语句不会消失.这段代码不是数据,它不能被程序操纵.

所有可以操纵的是初始值i.而另一方面,该值无法按代码的方式执行.您可以调用该函数foo,但不能调用该变量i.i数据也是如此,但它不是代码.

Lisp没有这个区别.程序代码也是可以操作的数据.您的代码可以在运行时使用该函数foo,也可以添加另一个if语句,也许可以更改for循环中的条件,或者将调用替换为baz另一个函数调用.所有代码都是可以检查和操作的数据,就像上面的函数可以检查和操作整数一样i.

  • 自修改代码通常是间接的.您创建了一个二进制blob,恰好与机器指令相对应,然后将其存储在内存中的已知位置,然后跳转到该指针.你没有得到类型检查或任何东西.特别是,你无法要求"函数f的源代码".当然,你可以获得一个指向该函数的指针,并读取为它生成的机器代码,但你无法使用该语言来处理它.它不允许您用您编写的语言操纵实际的程序代码,即您编写的内容. (2认同)

Cra*_*aig 15

我强烈推荐计算机程序的结构和解释,它实际上使用了方案,但这是一种lisp的方言.通过让你做许多不同的练习,它将帮助你"获得"lisp,并继续展示lisp如此有用的一些方法.


Ale*_*ell 10

我认为你必须对编译器编写者有更多的同情才能理解代码是多么基本的数据.我承认,我从未参加过编译器课程,但将任何足够高级的语言转换为机器代码是一个难题,LISP在很多方面类似于这个过程的中间步骤.与C"接近金属"的方式相同,LISP接近编译器.

  • 我所看到的是,Lisp允许您使用您的代码进行思考,而不是努力克服语法并希望表达您的意图.我一次学习一下Racket,就像是从监狱里释放出来的,我甚至都没有意识到自己所处的位置.我的思绪被剥夺了枷锁:我花了两个学期的Java,现在当我看到有限的时候我的想法是(我本来应该知道的更好!我是一名物理和数学学生),我感到一种深深但无助的遗憾(拒绝自怜). (3认同)
  • *(续)*在了解到电动工具广泛可用之后,您可能会在构建自己的乡村别墅,家具和手工灌溉之后感受到这种感觉."在如此不必要的困难下,我工作了这么长时间?" 这看起来很戏剧性,但这是我在学习的时候能够以任何一般方式完成一些简单的任务,而不仅仅是以Java语法和语言强加的限制方式.恢复了和谐.解除了负担. (3认同)

z5h*_*z5h 8

这对我有用:

  1. 阅读"The Little Schemer".这是让你在Lisp模式下思考的最短路径(减去宏).作为奖励,它相对较短/有趣/便宜.

  2. 找一本好的书/教程来开始使用宏.我发现"计划编程语言"第8章是Scheme的一个很好的起点.

http://www.ccs.neu.edu/home/matthias/BTLS/

http://www.scheme.com/tspl3/syntax.html


Luí*_*ira 5

在Common Lisp中,“代码就是数据”可以归结为这一点。例如,编写时:

(add 1 2)
Run Code Online (Sandbox Code Playgroud)

您的Lisp系统将解析该文本并生成一个包含三个元素的列表:符号ADD以及数字1和2。所以现在它们就是数据了。您可以使用它们进行任何操作,替换元素,插入其他内容等。

有趣的是,您可以将这些数据传递给编译器,并且因为可以使用Lisp本身来操纵这些数据结构,所以这意味着您可以编写编写其他程序的程序。这听起来并不那么复杂,Lispers始终使用宏来做到这一点。因此,只需获取有关Lisp的书,然后尝试一下即可。