Programming languages 为什么多态消息在实践中比统一和回溯的组合更强大?

Programming languages 为什么多态消息在实践中比统一和回溯的组合更强大?,programming-languages,language-design,Programming Languages,Language Design,看待编程语言设计历史的一种方式是,子程序的引入带来了一场革命。二三十年后,人们认真考虑了子程序调用的两种改进: 多态消息 统一与回溯 在中断了20年之后,我刚刚用Prolog编程,并意识到统一和回溯是多么强大。然而,多态性赢了。为什么?猜测:信息传递更容易被附加到当时流行的实践中,并逐渐被吸收。Prolog思想的逐渐接受需要一种像90年代才发明的工具,比Smalltalk落后20年左右。既然Oz声称在一个干净的包中支持过程和逻辑编程,我认为原则上没有理由世界不可能走这条路,如果它在正确的时间

看待编程语言设计历史的一种方式是,子程序的引入带来了一场革命。二三十年后,人们认真考虑了子程序调用的两种改进:

  • 多态消息
  • 统一与回溯

在中断了20年之后,我刚刚用Prolog编程,并意识到统一和回溯是多么强大。然而,多态性赢了。为什么?

猜测:信息传递更容易被附加到当时流行的实践中,并逐渐被吸收。Prolog思想的逐渐接受需要一种像90年代才发明的工具,比Smalltalk落后20年左右。既然Oz声称在一个干净的包中支持过程和逻辑编程,我认为原则上没有理由世界不可能走这条路,如果它在正确的时间知道如何走。取而代之的是,这种模式与烧录磁盘包的态度和第五代人的失望联系在一起


(到目前为止,我自己还没有试过莫扎特/奥兹。我玩过Prolog。)

我对Prolog的体验是,当回溯搜索非常适合您的问题领域时,它非常有效。然而,如果情况不是这样的话,那么大部分的编程工作将投入到回溯搜索的斗争中,使之适应自己的需要


因此,我对这种情况的看法是,回溯搜索是一种过于狭窄的语言特性,无法普遍使用。如果我们看到统一和更灵活的搜索,那么我们可能会看到不同的发展过程。

我用Prolog做过很多编程,虽然我喜欢这种语言的表达能力,我必须同意斯文宁森的观点,只要你尝试做任何非声明性的事情,那么使用!运算符(剪切、放弃回溯选项)位于正确的位置,这极易出错

尽管不是完美的,但有一种语言能够优雅地将回溯和非声明性(命令式/副作用)代码结合起来,那就是Icon。它基本上将能够自然回溯的表达式与一般程序结构(例如语句)隔离开来,这样就比较容易看出回溯不会导致意外的结果,就像在Prolog中一样。我不确定为什么没有更多的语言基于这个执行模型,我的猜测是大多数程序员都陷入了顺序思维,回溯是令人困惑的

我不确定回溯是否直接与多态性相比较。对我来说,它更像是闭包的替代品,因为大多数语言中闭包的#1用法是自定义迭代(想想map/filter/fold等)。例如,在图标中,我可以说:

every write 10<(1..10)*2

诚然,这是一个有点连续的列表理解和咖喱可以简化这一点,并不是所有的图标代码都是如此简洁,但你得到的想法。图标版本不仅更具表现力,而且还有一个优点,即它不使用中间列表,并且在共同常规意义上是“懒惰的”,即它将在第二个元素上执行*2之前写出第一个数字。这意味着它允许您编写同样高效的代码,即使您最终没有使用生成的所有结果。

我立刻想到了剪切操作符: Prolog美观简洁,只要您愿意,并且可以声明式编程。一旦开始使用“剪切”操作符(即,在该位置剪切所有回溯),您必须仔细考虑太复杂的情况,以找到一个好的解决方案或从其他人/您的旧代码中理解代码


因此,优化回溯的问题似乎是这里的共识,4个答案中有3个(截至2011年8月12日)指出了这一点(Aardapel和svenningsson各有1个)

当所有系统都告诉您“否”时,回溯很难调试!有更好的Prolog编译器,但大多数人在大学被迫使用一个糟糕的编译器时已经受够了

UI代码是大多数程序员的起点,也是用户所看到的,Prolog似乎从来都不适合编写UI代码

在“多态消息”变得正常之前,人们使用函数指针来获得相同的结果,因此这是一个较小的步骤


Prolog代码对大多数程序员来说仍然是很难阅读的,但是大多数程序员至少可以理解一些C++代码,因为他们知道C.

或者排序你的子句,所以你不会意外地定义一个无限的搜索。
for (filter (map [1..10] \x.x*2) \x.x>10) \x.(write x)