【问题标题】:Does runtime generally use an imperative-like interpretation of functional language code运行时是否通常使用类似命令式的函数式语言代码解释
【发布时间】:2012-06-20 03:24:54
【问题描述】:

我有一个关于函数式语言解释器的一般性问题:

在运行时使用函数式语言与命令式语言相比实际上有什么优势(或进入解释器)?

我看到的所有问题(例如this)都没有真正解决这个问题,而且搜索中充斥着关于不同语言定义的争论。

编辑:精简到我最终需要回答的唯一问题。

【问题讨论】:

  • 你所说的优势是什么意思?
  • @sepp2k 就像我列出的具体示例一样:函数式编程语言似乎有各种共同特征。我想知道这些似乎将函数式编程与命令式风格区分开来的特性是否真的会在运行时产生任何影响,或者只是编码风格的更肤浅的差异将两者区分开来。有意义吗?
  • 我仍然不清楚您希望它以何种方式在运行时发挥作用。让我们将“更容易推理代码”作为引用透明性的优势之一。您如何判断这在运行时是否有所不同?这甚至意味着什么?或者作为(静态类型)函数式编程的另一个优点:“在编译时会捕获更多错误”。这在运行时会有所不同吗?我想你可以这样说,因为这意味着运行的程序更有可能在运行时表现出所需的行为。但这仍然是一种奇怪的思考方式。
  • 链末端的终极“解释器”是您的 CPU。这是完全必要的。
  • @SK-logic 或者,如果您斜视恰到好处,则完全可以使用。 :)

标签: haskell functional-programming ocaml interpreter imperative-programming


【解决方案1】:

简短的回答是:一切最终都会被编译成某种低级语言(汇编或虚拟机语言)。函数式语言和命令式语言处于同等地位:它们必须编译掉它们的抽象机制以适应机器上可用的内容。
语言的不同之处在于它们与底层低级代码的匹配程度(通过提供低级功能以在需要时手动优化代码)以及通过提供强大推理保证的清晰语义来启用或简化哪些优化。

例如,当编译为本机代码时,递归不是(通常)编译成循环,而是编译成到标签的跳转,就像循环一样:大多数汇编语言既没有循环也没有递归。当然,如果编译成有循环但没有跳转的虚拟机,就需要产生循环;这是一个问题,例如在 Java 虚拟机上,因为一般的尾调用比单独的循环更具表现力,您需要解决这个限制,放弃一些效率。

函数式程序的“优势”可能是因为语义表现更好,您可以更轻松地对程序进行推理,例如以更简单的方式表达优化。现在很多编译器都使用Single Static Assignment (SSA) 中间形式,它基本上是一种低级函数语言¹——尽管它是由编译器社区的人独立发现的。例如,当您消除变量突变并且变量在其所有范围内保持相同的值时,大多数优化都会更容易进行。有一些技术可以在more efficient ways 这样的功能中间形式上进行寄存器分配。

¹:参见 Andrew Appel 1998 年的短文:SSA is Functional Programming;如果你对SSA形式的细节感兴趣,这里有some reading notes关于SSA和其他功能中间形式的关系,例如CPS

您还可以从纯度(没有副作用,或者至少可以很好地控制哪些计算将没有副作用)和静态类型中获得优化优势。从纯度中,您可以获得强大的优化,例如 deforestationfusion(消除中间数据结构),并且从类型中您可以获得对值的形状的有力保证(这就是为什么一些动态语言试图允许某些受限形式的用于优化目的的类型注释)允许生成更好的代码。

关于访问低级功能:Fortran、C 和 C++ 可能是最好的、最广泛使用的“可以使用非常低级”的语言。一些语言试图提供其中的一些功能:例如ATS(最初是一种函数式编程语言,虽然它是如此裸机以至于很难看到)提供了对堆栈分配版本堆分配的良好控制Haskellthe CLR (C#,etc.) 提供未装箱的复合类型作为这种低级推理的特例,同样Rust 试图为您提供对内存消耗做出低级决策的方法。
但是,当您隔离一小部分对您的性能至关重要的代码并且您想优化它(放弃一些灵活性/简单性/可维护性)时,这当然很有用,但这不会改变您的生活在日常情况下,除非您是嵌入式/内核程序员。您可能会从允许您使用正确的抽象级别并花更多时间为您的问题选择正确的设计和算法的高效语言中获得更多的整体性能提升。当然,一个人可能想要两者兼得,这是可能的,但很困难。

【讨论】:

    【解决方案2】:

    在运行时使用函数式语言与命令式语言相比实际上有什么优势(或进入解释器)?

    是的。如果您使用函数式语言,其优点是解释器编写器可能完成得更快。如果使用命令式,可能会使用更少的内存和 CPU。

    所以,不管你怎么做,都有优势。

    但是,给定两个解释器,一个用命令式语言编写,另一个用函数式语言编写,并且进一步假设它们都是正确的,您无法从程序的结果中判断使用了哪个解释器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-29
      • 2010-10-09
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多