【问题标题】:How Functional language are different from the language implementation point of view从语言实现的角度来看,函数式语言有何不同
【发布时间】:2010-12-23 20:18:51
【问题描述】:

有一种全新的“函数式编程”范式,与过程式编程相比,它需要彻底改变思维模式。它使用高阶函数、纯度、monad 等,这些在命令式和面向对象的语言中通常看不到。

我的问题是这些语言的实现与命令式或面向对象的语言有何不同,例如内存管理或指针等内部结构。

有些函数式语言在 JVM 之上运行。这是否意味着这些语言在内部像 JVM 上的其他语言一样工作?

【问题讨论】:

  • 小吹牛:我不会将 FP 描述为“新范式”...(可能比以前稍微流行一些)

标签: haskell functional-programming lisp ml


【解决方案1】:

由函数式语言产生的代码使用了您在非函数式语言中不同程度上看到的许多特性。垃圾收集已成为一般用途。尾调用优化为done in GCC and VC++

然而,闭包是函数式编程的标志。你看不到一个没有另一个。如果您将“函数式语言”定义为仅指纯函数式语言,那么两者并不是同义词,因为您会在支持函数式编程的命令式语言中找到闭包(例如 Javascript 和 Scheme(这在技术上是命令式的,尽管函数式范式主要是用过的))。闭包可以通过调用堆栈的spaghetti stack 来实现,或者通过在退出堆栈帧时复制局部变量来实现,或者通过在堆上分配局部变量并让垃圾收集来处理它们。

一旦你有了闭包,匿名函数就相对容易了(使用解释器,它们真的很容易)。使用编译器,函数在编译时转换为字节码,字节码(确切地说,入口点的地址)在运行时与当前环境相关联。

函数组合可以依赖匿名函数。当编译器遇到函数组合运算符f . g 时,它会创建一个匿名函数来调用fg 这两个参数,并将一个的结果作为参数传递给另一个。

Monad 可以在 OO 语言中实现,它们只是不像在纯函数式语言中那样必要。 I/O monad 并没有什么特别之处,它们只是依赖于底层平台允许副作用这一事实。

【讨论】:

    【解决方案2】:

    函数式编程语言的实现使用了广泛的实现技术。这本书很好地介绍了 Scheme(一种 Lisp 方言)的实现:Lisp in Small Pieces by Christian Queinnec。

    【讨论】:

      【解决方案3】:

      我想有很多方面可以从函数式语言的特殊关注中受益,我想到的一个是:

      函数式语言大量使用递归。所以任何实现都应该尝试优化这种情况。例如。识别尾递归并在内部转换为循环(从而节省函数调用开销,如堆栈保存/恢复)。 (http://en.wikipedia.org/wiki/Tail_recursion)

      【讨论】:

      • 是的,显然 FP 有优点也有一些缺点,但问题在于它们的内部工作原理。
      【解决方案4】:

      函数式编程语言(例如 Haskell)的实现通常与命令式语言的实现非常不同。您可以阅读有关一种方法here。尽管这篇论文已经有好几年了,但我相信这些想法仍在使用。

      【讨论】:

      • 虽然这本书有点旧,但仍然是一本非常好的读物。对我来说,这是对实现函数式语言之美的真正 AHA 体验。
      【解决方案5】:

      我想到的最大区别是函数式语言的设计往往使源代码desugared 成为数学上简单而强大的中间语言。这种语言通常包含 lambda、函数调用、if/else、机器类型,诸如 let 之类的东西,仅此而已。转换后的代码是深度嵌套的、冗长的,并且实际上不适合人类阅读。表面语法被抛弃了。

      像这样的语言的编译器必须进行一些内联​​和一些闭包优化才能生成体面的代码。 (对我来说,这些基线闭包优化似乎很重要——逃逸分析等等——但它可能只是缺乏熟悉。)

      【讨论】:

        【解决方案6】:

        所有东西都在同一个处理器上运行(因此也使用相同的汇编指令),所以只要你走得够深,内部一切都是一样的。

        【讨论】:

        • 我不是这方面的专家,但一切都运行在相同的汇编指令 (x86/x86_64) 上这一事实似乎更多是 x86 架构占主导地位的结果。在过去,Lisp 机器有专门为 Lisp 设计的处理器。 en.wikipedia.org/wiki/Lisp_machine
        • 当然。但我更多地指的是假设您在同一平台上运行所有类型的语言,在某种程度上,它们都将归结为同一件事。 (功能、程序、基于逻辑等)
        • 这毫无意义。 Lisp 编译器与 C 编译器的实现方式不同,使用不同的指令序列并编译为不同的指令序列。所有车辆在同一条道路上行驶并不会使所有车辆的外观或工作方式都相同。有些有两个轮子,有些有四个轮子,等等。
        • 但所有这些最终都会转化为在汽车和道路之间施加的力。同样,重点不在于语言相同,而只是如果您深入研究,语言都是独立于语言的资源的接口。
        • @Dav:特别是,Dinesh 正在询问实现函数式语言的编译器/解释器。
        【解决方案7】:

        @outis:虽然语言可能支持它们,但闭包与函数的数学概念冲突,就像副作用一样:它们允许您从相同的参数获得不同的结果。这使得闭包是程序性的,而不是功能性的。

        也就是说,有一些效率参数支持闭包而不是全局变量(尤其是在编译器实现的上下文中)。 [但我知道不直接提供闭包的函数式语言,即使可以实现“类似工作”。]

        (但是,柯里化类似于闭包,不会受到这种冲突的影响,并且确实经常出现在函数式语言中。)

        无论如何,在我看来,函数式编程语言是努力使计算像数学函数一样可表示的语言。这意味着优化偏向于优化功能。

        假设,至少,函数式语言允许机器处理比纯过程方法有用的更深层次的抽象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-11
          • 2017-09-19
          • 2011-10-11
          • 2011-12-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多