【问题标题】:What does “Data is just dumb code, and code is just smart data” mean? [closed]“数据只是愚蠢的代码,代码只是智能数据”是什么意思? [关闭]
【发布时间】:2009-05-16 06:29:16
【问题描述】:

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

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

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

【问题讨论】:

  • 如果你不知道它的意思,你怎么能说它是“优雅的措辞”?
  • 起初我认为它是一种交叉,但现在我认为它是一种抗代谢物。
  • 这是我作为程序员最重要的见解之一,它实际上是白板编程问题的范例。甚至还有一个著名的视频系列,在白板上进行了解释。对于机器的热爱,这里怎么能算题外话?

标签: terminology sicp


【解决方案1】:

这是 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 没有描述图灵完备的编程语言。它只是结构化数据。它的结构包含一些智能,可以让它控制其解释上下文的行为——但不是很多智能。另一方面,它比一般网页上显示的文本段落包含更多智能:这些都是非常愚蠢的数据。

【讨论】:

  • 您的回答很好地解释了这句话在理论上的含义,但我认为在实际修改您处理程序的方式方面还有一些空间可以涵盖它的含义。您可能还想介绍有关此格言如何成为 OOP 的核心洞察力的想法。即,将相关代码和数据封装在一起,语义上将访问器视为来自调用上下文的 POV 的底层数据等的能力。
【解决方案2】:

在安全方面:由于缓冲区溢出,您认为无害的数据(例如图像)可以作为代码执行并占用您的机器。

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

这些开发人员没有意识到,既然这些“数据”会影响程序的行为,那么它确实是代码;它可能会破坏程序,并且在这种更改之后不需要进行完整测试的唯一原因是,如果正确完成,可配置值具有非常具体、有据可查的效果,任何无效值或损坏的文件结构都将被程序。

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

【讨论】:

  • +1。现在有一种令人担忧的全球趋势,将所有内容存储到丑陋的 XML 文件中,随着时间的推移,这些文件变得越来越复杂和难以理解。正如您所说,它暴露了普通程序员对代码和数据之间差异的缺乏洞察力。
  • 你有一个很好的观点,我会在设计我的下一个超级超级棒的全能灵活系统时考虑这一点;-)
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

    Lisp 语言只是将其视为其数据。所以数据和代码之间没有分离,它们都是看起来像 AST 树的列表。

    【讨论】:

      【解决方案5】:

      代码绝对是数据,但数据绝对是并不总是代码。让我们举一个基本的例子——客户名称。它与代码无关,它是功能(必不可少),而不是应用程序的技术(偶然)方面。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-02
        • 2021-05-30
        相关资源
        最近更新 更多