“数据只是愚蠢的代码,代码只是智能数据”是什么意思?

时间:2009-05-16 06:29:17

标签: terminology sicp

我刚刚在The Structure And Interpretation of Computer Programs中发现了一个想法:

  

数据只是愚蠢的代码,而代码只是智能数据

我不明白这意味着什么。有人可以帮助我更好地理解它吗?

5 个答案:

答案 0 :(得分:37)

这是SICP的基础课程之一,也是计算机科学最强大的思想之一。它的工作原理如下:

我们认为“代码”实际上并没有能力自行完成任何事情。代码仅在解释的上下文中定义程序 - 在该上下文之外,它只是一个字符流。 (真的是一个比特流,它实际上是一个电脉冲流。但是让它保持简单。)代码的含义由运行它的系统定义 - 而这个系统只是将您的代码视为告诉它您想要做什么的数据。 C源代码由C编译器解释为描述您希望它创建的目标文件的数据。加载器将目标文件视为描述您要排队等待执行的某些机器指令的数据。机器指令由CPU解释为定义它应该经历的状态转换序列的数据。

解释语言通常包含将数据视为代码的机制,这意味着您可以以某种形式将代码传递到函数中然后执行它 - 甚至在运行时生成代码:

#!/usr/bin/perl
# Note that the above line explicitly defines the interpretive context for the
# rest of this file.  Without the context of a Perl interpreter, this script
# doesn't do anything.
sub foo {
    my ($expression) = @_;
    # $expression is just a string that happens to be valid Perl

    print "$expression = " . eval("$expression") . "\n";
}

foo("1 + 1 + 2 + 3 + 5 + 8");              # sum of first six Fibonacci numbers
foo(join(' + ', map { $_ * $_ } (1..10))); # sum of first ten squares

像scheme这样的语言有一个“一流函数”的概念,这意味着你可以将一个函数视为数据并在不进行评估的情况下传递它,直到你真正想要它为止。

结果是“代码”和“数据”之间的划分几乎是任意的,只是透视的一个功能。抽象级别越低,代码就越“智能”:它必须包含有关应如何执行的更多信息。另一方面,解释器提供的信息越多,代码就越愚蠢,直到它开始看起来像没有智能的数据。

编写代码的最有效方法之一就是简单描述您需要的内容:数据将转换为代码,描述如何通过解释上下文获取您所需的内容。我们称之为"declarative programming"

有关具体示例,请考虑HTML。 HTML没有描述图灵完整的编程语言。它只是结构化数据。它的结构包含一些智能,可以控制其解释上下文的行为 - 但不是很多智能。另一方面,它包含比普通网页上显示的文本段落更多的智能:这些都是非常愚蠢的数据。

答案 1 :(得分:7)

在安全性的上下文中:由于缓冲区溢出,您认为数据因此无害(例如图像)可以作为代码执行并对您的机器执行操作。

在软件开发的背景下:许多开发人员非常害怕“硬编码”事情,并且非常热衷于提取可能必须更改为配置文件的参数。这通常基于这样的想法,即配置文件只是“数据”,因此可以轻松更改(客户满意),而不会引起更改代码中任何内容的问题(编译,部署,测试)。

这些开发人员没有意识到,因为这个“数据”会影响程序的行为,所以它确实是代码;它可能会破坏程序,并且在这样的更改之后不需要完整测试的唯一原因是,如果正确完成,可配置值具有非常具体的,记录良好的效果,并且任何无效值或损坏的文件结构都将被捕获该计划。

但是,经常发生的事情是配置文件结构本身就成了一种编程语言,完成了控制流和所有内容 - 一个记录错误,具有古怪的语法和解析器,只有最有经验的开发人员在团队中可以触摸而不会完全破坏应用程序。

答案 2 :(得分:2)

因此,在像Scheme这样的语言中,甚至将代码视为第一类数据。您可以像处理其他代码一样处理函数和lambda表达式,比如将它们传递给其他函数和lambda表达式。我建议继续阅读本文,因为这一切都会变得非常清楚。

答案 3 :(得分:2)

这是您应该通过编写编写器来理解的。

编译器中的一个常见步骤是将程序转换为抽象语法树。表示通常会像[+,2,3]这样的树,其中+是根,2,3是孩子。

Lisp语言只是将其视为数据。因此,数据和代码之间没有分离,这两个列表看起来都像AST树。

答案 4 :(得分:0)

代码肯定是数据,但数据肯定是并不总是代码。我们来看一个基本的例子 - 客户名称。它与代码无关,它是功能性(必要),而不是应用程序的技术(偶然)方面。

您可能会说任何技术/意外数据都是代码,而功能/基本数据则不是。