Haskell是托管语言吗?
我是Haskell的一名完全新手。 有一件事情总是让我感到困惑的是,Haskell是一种托管(从MS借用的术语)语言(如Java)还是像C这样的编译本机代码?
GHC页面说这个“GHC直接将Haskell代码编译为本地代码或使用LLVM作为后端”。
在“编译为本地代码”的情况下,垃圾收集等功能如何能够在没有JVM之类的情况下实现?
/更新/
非常感谢你的回答。 从概念上讲,请你帮忙指出我对Haskell垃圾收集的下列理解中的哪一个是正确的:
GHC将Haskell代码编译为本地代码。 在编译的过程中,垃圾收集例程将被添加到原始程序代码中?
要么
有一个程序与Haskell程序一起运行以执行垃圾回收?
据我所知,术语“托管语言”具体指的是一种针对.NET /公共语言运行时的语言。 所以不,Haskell不是托管语言,也不是Java。
关于Haskell编译的内容:正如您引用的文档所述,GHC将Haskell编译为本机代码。 它可以通过直接发布本地代码或首先发出LLVM代码然后让LLVM将其编译为本机代码来实现。 无论哪种方式运行GHC的最终结果是本机可执行文件。
除GHC外,Haskell还有其他的实现 - 最着名的是Hugs,它是一个纯粹的解释器,永远不会生成可执行文件(本地文件或其他文件)。
没有像JVM这样的东西,垃圾收集功能怎么可能?
与使用JVM的可能方式相同:每次分配内存时,都将其注册到垃圾收集器。 然后,垃圾收集器会按照给定的垃圾收集算法的步骤运行。 GHC编译的代码使用世代垃圾收集。
为了回应你的编辑:
GHC将Haskell代码编译为本地代码。 在编译的过程中,垃圾收集例程将被添加到原始程序代码中?
基本上。 除了说“垃圾收集例程将被添加到原始程序代码”可能会画错误的图片。 GC例程只是每个Haskell程序所链接的库的一部分。 编译后的代码只是在适当的地方包含对这些例程的调用。
基本上所有的功能都是每次调用malloc时调用GC的alloc函数。
只要看看C语言的任何GC库以及它是如何使用的:你需要做的就是#包含库的头文件并链接库,并用GC库的alloc函数替换malloc的每一个出现的地方(并且删除所有的free
函数)和巴姆,你的代码被垃圾收集。
有一个程序与Haskell程序一起运行以执行垃圾回收?
没有。
Haskell是否是一种托管(从MS借用的术语)语言,如Java
GHC编译的程序包含垃圾收集器。 (据我所知,Haskell的所有实现都包含垃圾收集,但这不是规范的一部分。)
或像C这样的编译原生代码?
GHC编译的程序被编译为本地代码。 拥抱解释程序,并不编译为本地代码。 据我所知,还有几个其他的实现可以编译为本地代码,但我将它们分开列出,因为我对这个事实没有那么自信。
在“编译为本地代码”的情况下,垃圾收集等功能如何能够在没有JVM之类的情况下实现?
GHC编译的程序包括一个运行时系统,它提供了一些基本功能,如M对N绿色线程,垃圾收集和IO管理器。 从某种意义上说,这有点像“像JVM一样”,因为它提供了许多相同的功能,但实现方式却有很大不同:所有体系结构中都没有公共字节码(因此没有“虚拟机”) 。
我对哈斯克尔垃圾收集的下列理解中的哪一个是正确的:
情况1是正确的:运行时系统代码在编译期间被添加到程序代码中。
“托管语言”是一个超载的术语,所以这里是一个单词的答案,然后是一些通常不同意义的细节:
按照CLR目标进行管理
不 ,Haskell不能编译到Microsoft CLI的IL。
那么,我读过一些解决方案可以做到这一点,但imo,不...... CLR不是为FP编译的,并且严重缺乏优化,可能会产生一种研究语言的性能。 如果我个人真的想要定位CLR,我会使用F# - 这不是一种功能语言,但它很接近。
注意这是“托管语言”这个术语最准确和最真实的含义。 接下来的意义是错的,但不幸的是,不幸的是很普遍。
像自动垃圾收集一样进行管理
是的 ,这是非常必要的。 我的意思是,超出了规范:如果我们不得不收集垃圾,它会破坏功能主题,使我们在高海拔地区工作,这是我们心爱的家园。
它也会强化不纯物和记忆模型。
像编译成虚拟机运行的字节码一样进行管理
否(通常) 。
这取决于你的后端:不仅我们今天有不同的Haskell编译器,一些编译器有不同的后端 - 甚至有JavaScript的后端!
因此,如果您确实想要定位虚拟机,则可以使用现有的/为其创建后端。 但Haskell不需要它。 所以就像你可以编译成本地的原始二进制文件一样,你可以编译为其他任何东西。
与C#1,VB.NET等CLR语言相比,与Java等不同,您不必针对JVM,而像Haskell这样的CLR,Mono等完全不需要虚拟机。
GHC就是一个很好的例子。 在GHC中编译时,它不会直接编译为二进制文件,而是编译为中间语言(称为Core),然后在进行到称为STG的另一种语言之前从核心到核心进行优化,然后才转到代码(如果你告诉它,它可以停在那里).2最近你也可以用它来编译成LLVM字节码(这受到一些很棒的优化)。 随着LLVM后端,GHC能产生更快的疯狂计划。 有关它和关于GHC后端的更多信息,请点击此处。
下图说明了GHC编译管道,在这里您可以找到关于各个阶段的更多信息。
看到三个不同目标的底部叉子? 那些是我所指的后端。
1未来的异常和有趣的事实:Microsoft目前正在开发本地.NET! 狡猾地命名为:Microsoft .NET Native。