3

I wish that John McCarthy was still alive, but...

From LISP 1.5 Programmer's Manual :

LISP can interpret and execute programs written in the form of S- expressions. Thus, like machine language, and unlike most other higher level languages, it can be used to generate programs for further execution.

I need more clarification about how machine language can used to generate programs and how Lisp can do it?

4

3 回答 3

5

机器语言可以在运行时改变自己。我做的最后一次汇编编程是针对 MS DOS 和我在测试其他程序之前运行的常驻程序。当我的程序出现异常时,按键切换到常驻程序,并且可以查看正在运行的程序并在恢复之前直接对其进行更改。这很方便,因为我没有调试器。

LISP 从一开始就有这个,因为它最初是被解释的。您可以在运行时更改函数的定义,并且整个语言在运行时始终可用,eval甚至define. 当它开始编译时,它并没有像 Algol 那样编译,而是部分允许解释和编译的代码同时混合。它的代码结构是列表结构,而符号是一种数据类型,这一事实促成了这一点。

上次我看到 McCarthy 的采访时,有人问他对现代编程语言的看法(不是 LISP 家族,而是据说受 LISP 影响的 Algol 家族语言 Ruby),在回答之前他问他们是否可以将代码表示为数据(比如列表结构)。在他看来,Ruby 仍然落后于 60 年代的 LISP。

Algol 家族中出现了许多新的编程语言,其中一些最有前途的语言,如Perl6Nemerle,正越来越接近 LISP 在 60 年代所具有的功能。

于 2013-08-14T00:08:24.110 回答
5

也就是说,机器代码可以直接将机器指令写入内存并跳转到那些指令执行它们;事实上,这是许多攻击媒介侵入软件的基础。

关键是,当您编写机器代码时,很容易生成机器代码。但是,当您使用 C 之类的编译语言编写代码时,您不能只在运行时生成 C 代码然后执行它——除非您的程序包含 C 编译器。

Lisp——以及现在许多其他语言,尤其是像 Perl、Python、Ruby、Tcl、Javascript 和命令 shell 这样的“脚本语言”——能够执行在运行时生成的代码。在 Lisp 中,由于代码和数据具有相同的结构,因此这通常比在其他语言中更少的工作,在其他语言中,要评估的代码通常是一个必须被解析的字符串。(虽然 Perl 能够eval使用块而不是字符串,这让编译器可以提前对文字代码进行解析。)

于 2013-08-13T22:43:28.883 回答
2

机器语言程序可以用任意字节填充内存区域。然后他们可以直接jump到该区域的开始,从而立即执行。

Lisp 语言程序可以轻松地在内存中创建任意 S 表达式,使用cons. 然后他们可以调用eval这些 S 表达式来评估(解释)它们。

高级语言程序可以很容易地用代表语言语法中新代码的字符填充内存区域。但是他们不能运行这样的代码。

于 2013-08-14T17:02:45.637 回答