Haskell中的文学编程真的是“文学编程”吗?

16

我还不了解文艺编程的概念。我正在阅读唐纳德·科诺斯(Donald Knuth)的论文(PDF),关于这个主题,一开始在介绍中他说:

与其想象我们的主要任务是指示计算机做什么,不如集中精力向人类解释我们希望计算机做什么。

文艺编程实践者追求的是一个易于理解的程序,因为它的概念已按照最适合人类理解的顺序进行介绍,使用正式和非正式的方法相结合,这些方法互相强化。

随后,再看下去:

关于程序的一件事是它的结构关系。复杂软件由简单的部分和部分之间的简单关系组成;程序员的任务是陈述这些部分和关系,无论以何种最适合人类理解的顺序——而不是某种严格确定的自上而下或自下而上的顺序

(...)

自上而下编程让你对前进方向有强烈的想法,但它迫使你将许多计划记在脑中;悬念会因为直到最后没有确定下来而累积。自下而上编程具有你不断运用越来越强大的铅笔的优点,因为建立了越来越多的子程序;但它迫使你将整个程序组织推迟到最后一刻,所以你可能会毫无目的地挣扎。

因此,WEB语言允许人以“意识流”的顺序表达程序. TANGLE能够混淆所有东西,并按照PASCAL编译器要求的排列进行排序. WEB的这个特性也许是其最大的优点;

上面的摘录让我对这个主题感兴趣,所以我更深入地调查了一下。在任何搜索引擎提供的结果中都很容易看出Haskell与文学编程之间的关系,但我没有看到“最适合人类理解的顺序”。相反,我看到了非常完美的文档,同时保持计算机要求的顺序才能工作。

  • 你能使用“文学编程”这个术语并去掉那个顺序问题吗?
  • 是否有任何其他定义文学编程的方式不需要 "意识流" 的顺序特征?
  • Haskell 真的具备文学编程能力(使用 Knuth 的定义)吗?

最后,我必须说作为个人观点,即使 Haskell(可能还有许多其他语言)并不是 Knuth 的文学编程,当涉及到方法和算法的详尽描述时,我仍然喜欢这个想法。当注释远远超过代码时,它有很好的用途。


WEB 和 TANGLE 是最初 D. Knuth 在他的第一个文学编程实现中使用的系统的一部分。


2
在最高层级上,Haskell表达式可以以任何顺序出现(即使在函数内部,您也可以通过巧妙地使用“where”和“let”来随意排序)。因此,如果您有一个非常复杂的模块,您可以首先表达主要思想,该思想可能依赖于其下方的定义,解释该主要思想,然后继续将其分解为其下方的部分。 - user2407038
当Knuth与朋友们设计TeX时,他选择了标准Pascal编译器作为代码生成目标。标准Pascal对于它想要的服务方式非常严格(即获得单通编译器),因此很难将代码编写成散文形式。现代语言如Haskell则更加宽松,这主要是关于如何将可运行代码与文档混合的问题。 - Thorbjørn Ravn Andersen
1个回答

16

Haskell在大部分情况下都非常灵活,不受顺序的限制。在Haskell模块内,所有声明和定义都可以以任何顺序出现。由于引用透明性,很容易提取子问题以便在其他地方实现。

顺序匹配是顺序对结果有影响的主要领域。一个函数的所有方程必须放在一起,并且由于它们按顺序匹配,因此它们不能总是被重新排序。然而,我认为这不是一个重要的限制,因为(a)这通常是非常局部的,(b)具有大量方程的大型函数可以(并且可能应该)被重构成更小的部分,这样更容易进行重新排序。

也许最烦人的约束是import声明必须位于模块顶部。这确实会稍微打乱思路,许多用Haskell编写的文艺程序以类似“不要在意这些导入,你将在后面看到我们需要它们”的语句开始。更符合Knuth对文艺编程的定义的做法是在文本中更自然的地方命名导入,在上下文清楚的情况下说明它们为什么是必要的。

除此之外,我认为Haskell非常适合文艺编程。它可能不完全符合Knuth的定义,但我认为它已经足够接近了。


8
为什么“import”语句需要放在文件顶部,我一直很好奇。 - Gabriella Gonzalez
你不能使用一个预处理器来处理这些东西吗?这不是CWEB所做的基本工作吗? - Wes
2
@Wes:是的,这基本上就是CWEB所做的。但是内置语言和编译器支持有很大的优势,我认为如果没有它,文学编程在Haskell博客社区中不会变得如此流行。而且它全部都是熟悉的Haskell语法,你不需要再额外学习CWEB的语法。 - hammar
@wes,预处理器引入了额外的复杂性,因为您真正希望各种工具知道您拥有原始文档,而不仅仅是预处理器生成的修改副本。编辑错误文件的情况发生得太频繁了。 - Thorbjørn Ravn Andersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接