5

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

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

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

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

4

2 回答 2

29

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

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

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

¹:参见 Andrew Appel 1998 年的短文:SSA 是函数式编程;如果您对 SSA 形式的详细信息感兴趣,这里有一些关于 SSA 与其他功能中间形式(例如CPS )之间关系的阅读笔记

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

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

于 2012-06-20T07:49:01.240 回答
0

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

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

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

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

于 2014-02-13T15:34:47.383 回答