scala - 名称值/表达式保存在函数程序中的什么位置?

标签 scala haskell functional-programming erlang

在C#中,所有的值字段如int、float都保存在栈中,所有的引用变量指针都保存在栈中,而实际值保存在堆中。 (希望我的理解在这里是正确的)。
1. 由于在函数式编程模型中没有值和引用类型,名称符号值保存在哪里?
2.栈和堆在函数式程序中如何发挥作用?
谢谢

最佳答案

您正在尝试将 C#(一种特定语言)与函数式语言作为一个整体进行比较。这是苹果与橙子的比较(或者更准确地说,苹果与香料的比较?)。

在命令式语言中,您已经可以观察到存储在堆栈中的值与存储在堆中的值之间的差异。例如,C 和 C++(据我了解)允许程序员手动选择他们想要的任何类型的这两种方式中的哪一种。

另一个微妙之处是语言向程序员保证与语言实现的方式之间的区别。一个例子是 Oracle 的 Java VM 的最新版本有一项他们称之为 "escape analysis" 的优化。 ,如果 VM 可以证明对象引用没有逃逸方法(执行内联后确定),则可以在堆栈上分配对象。因此,即使 Java 将其对象类型称为“引用”类型,但这并不意味着它将分配到堆中。引用 this article by Brian Goetz :

The Java language does not offer any way to explicitly allocate an object on the stack, but this fact doesn't prevent JVMs from still using stack allocation where appropriate. JVMs can use a technique called escape analysis, by which they can tell that certain objects remain confined to a single thread for their entire lifetime, and that lifetime is bounded by the lifetime of a given stack frame. Such objects can be safely allocated on the stack instead of the heap. Even better, for small objects, the JVM can optimize away the allocation entirely and simply hoist the object's fields into registers.

类似的考虑也适用于函数式语言——这完全取决于 (a) 语言 promise 的内容,以及 (b) 语言实现的工作方式及其复杂程度。但我们可以将函数式语言世界分为两个重要阵营:

  1. 渴望 函数式语言,例如 Scheme、Scala、Clojure 或 ML。
  2. 惰性函数式语言,例如 Haskell。

eager 语言有几种类型的实现:

  1. 纯基于堆栈的实现。它们的工作方式与现代命令式语言相同。 Common Lisp 就是这样工作的。由于 JVM 函数式语言使用与 Java 相同的 VM,因此它们也是如此。
  2. 纯延续传递风格的实现。这些是完全无栈的——所有东西,包括激活帧,都分配在堆上。这些使得支持变得容易 tail-call optimizationfirst-class continuations .我相信这项技术是由 Scheme 实现开创的,并且也被新泽西州标准 ML 编译器使用。
  3. 混合实现。这些通常试图主要基于堆栈,但也支持尾调用优化,也许还有一流的延续。示例:一堆随机 Scheme 系统。

惰性语言是另一回事,因为传统的调用堆栈实现不会直接转化为惰性求值。 The GHC Haskell compiler is based on a model called the "STG Machine" ,它确实使用了堆栈和堆,但是 STG 堆栈的工作方式与命令式语言不同; STG 堆栈中的条目不像传统堆栈条目那样对应于“函数调用”。

关于scala - 名称值/表达式保存在函数程序中的什么位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25754442/

相关文章:

javascript - lambda 长深

f# - 如何在功能上迭代 f# 中列表中的每个项目一次?

regex - scala:按commnas分割字符串,忽略引号之间的逗号

scala - 如何在编译时使用 shapeless 将 case 类字段的名称作为字符串/符号获取?

scala - 我应该将 nullable 设置为 false 还是 true?

opengl - Haskell GLUT 库中的 ($=)(美元等于)运算符有什么作用?

haskell - 字符转字符串函数

python - 嵌入式用户定义表达式的安全实现策略

scala - Play Framework : Logging time

facebook - 在 haskell 中编写 facebook 应用程序的最佳方法是什么?