声明性语言的实现细节本身是否必要

时间:2010-02-08 19:53:14

标签: language-agnostic programming-languages functional-programming declarative imperative

我正在阅读Tomas Petricek撰写的“功能编程”。 Jon Skeet和我理解声明和声明之间的区别命令式编程。

我想知道的是原始运算符&实现的函数是由命令式运算符构造的声明性语言。功能

干杯

AWC

5 个答案:

答案 0 :(得分:6)

如果我理解你的问题,我认为这不是一个严格的规则。例如,您可以使用像Lisp这样的函数语言来为自己创建解释器。在这种情况下,实现细节以函数方式实现(因为Lisp是一种函数式语言)。

此外,如果您的语言是图灵完成,您可以使用它来实现任何其他语言的解析器/解释器/编译器。有必要的图灵完备语言和功能/声明性图灵完备语言。

但是所有代码最终都是在汇编或机器代码上完成的,这本质上是必要的。理论上,我上面所说的是真实的,但显然不是在实践中:)。

作为一个有趣的历史,LISP是一个完全理论的结构;它是计算机语言的数学符号。它仍然是理论上的,直到LISP的eval函数由Steve Russel在IBM 704上的机器代码中实现:

根据Paul Graham在Hackers&画家,p。 185,麦卡锡说:“史蒂夫罗素说,看,我为什么不编程这个评估......,我跟他说,你好,你好,理论与实践相混淆,这个 eval用于阅读,而不是用于计算。但他继续前进并做到了。也就是说,他将我的论文中的eval编译成IBM 704机器码,修复了bug,然后将其作为一个广告Lisp解释器,它当然是。所以在那一点上,Lisp基本上具有它今天的形式......“(强调我的)

再一次,理论与实践之间的微妙之处。 :)

答案 1 :(得分:3)

低级别机器(CPU,汇编语言级别)势在必行,所以很明显在某些时候实现必须考虑到这一点。但是, Implementing certain kinds of functional languages like Haskell采用了一些非常明显的方法来创建具有良好性能的运行时。

奇怪的是,大多数命令式语言经历了一个阶段,其中所有代码都被转换为更具声明性:

这是一个直接编译Scheme(functional)到C代码(命令式)的例子:

答案 2 :(得分:2)

你的问题有点不清楚。在引擎盖下,处理器指令本质上是必不可少的。如果您的代码应该在von Neumann机器上运行,那么它最终应该作为命令式代码运行。

有可能构建一个本身支持这些操作的机器(具有某些特定的体系结构)。事实上,LispM旨在帮助运行Lisp程序。虽然我不熟悉LispM的硬件特性,但它可能有资格在更具声明性的层面上提供一些原始操作。

答案 3 :(得分:2)

  

声明性语言是由命令式运算符构建的吗?功能

有时。它是实现的属性,而不是语言

在20世纪80年代,许多人将功能程序编译成图形,然后将图形重写为更简单的图形。这种计算通常涉及到更新图形,但除此之外它就像你想要的声明一样。要了解更多信息,请查看“图表缩减”或阅读Chris Clack和Simon Peyton Jones撰写的“四冲程减速引擎”。

最终编译器编写者想出了通过将函数程序直接编译为本机机器代码来获得更好性能的方法。如果本机是典型的商用机器,这意味着典型的命令操作。但是,如果你查看麻省理工学院Arvind教授的开创性工作,他的小组设计并构建了数据流机器,其中基本的计算操作本质上更具说明性。这是一项伟大的工作,但是所有在20世纪80年代蓬勃发展的专用架构已经被微软/英特尔的良性循环所摧毁(更多的软件 - >更多的PC销售 - >更便宜的处理器 - >更多的PC销售 - > ... - > $ 300上网本真的很酷的东西。)

答案 4 :(得分:0)

实施是'隐藏在引擎盖下。它可以用任何范例构建。

声明性程序只是一些或多或少的“通用”命令式实现/ vm的数据。

加号: 以某种硬编码(和检查)格式指定一个数据比直接指定一些命令算法的变体更简单且更不容易出错。一些复杂的规范只能直接编写,只能以某种DSL形式编写。 DSL和数据结构中使用的最佳和频率是集合和表格。因为你没有元素/行之间的依赖关系。当你没有依赖关系时,你可以自由修改和轻松支持。 (比较具有类的模块 - 使用您喜欢的模块以及具有脆弱基类问题的类) 声明性和DSL的所有商品都立即从数据结构(表和集)的好处中获得。 另一个好处 - 如果DSL或多或少是抽象的(设计良好),你可以改变声明性语言vm的实现。例如,进行并行实现。或将其移植到其他操作系统等所有良好的模块化隔离接口或协议为您提供了这种自由和简单的支持。

弊: 你猜对了。通用(并由DSL参数化)命令式算法/ vm实现可能比特定的更慢和/或内存饥饿。在某些情况下。 如果这种情况很少见 - 只要忘掉它,就让它变慢。如果它是frequient - 你总是可以为这种情况扩展你的DSL / vm。在某个地方放慢所有其他情况,确定......

P.S。框架在DSL和命令之间是中途。并且作为所有中途解决方案......它们结合了缺点,而不是利益。他们不那么安全而且不那么快:)看看万能行业的杰克 - 它是强大的简单ML和灵活的元素Prolog之间的中间点......它是一个什么样的怪物。你可以将Prolog看作是一个只有布尔函数/谓词的Haskell。它的灵活性对Haskell有多么简单......