我几乎90%确信此问题的标题是错误的,但是我不知道正确的标题是什么(如果有建议,我会很乐意编辑标题!)。
在阅读Haskell和该语言的核心原理时,您总是会发现它是一种“基于lambda表达式”的语言。我记得在某处读过,这意味着最后,main
函数只是被“处理”为一个大的lambda,所有内容都被内联,基本上您的整个代码成为一个单独的,巨大的lambda表达式。
我的问题是:
我上面说的是真的吗?
如果问题1的答案为“是”,那么是否有任何...反编译器/部分编译器/预处理器?我知道this,使您可以看到C / ++和Haskell等语言背后的汇编代码,但是有什么我可以用来探索生成的lambda表达式的东西吗?
这个问题是从纯粹的教育角度提出的,并不旨在寻求解决特定问题的方法。我只是希望了解更多有关我发现非常着迷的语言。
答案 0 :(得分:3)
让我们区分Haskell的语义和GHC的实现。主要是因为我们在语言语义上使用的术语与在汇编中使用的术语不同,而且还因为其他一些编译器的行为可能不同于GHC。
每个Haskell程序都定义main
,它是类型IO ()
的表达式。我不喜欢将其称为“ lambda表达式”,因为该类型表明它不是函数。 main
的定义是一些嵌套的函数调用树。甚至do
块中的连续行都被定义为对函数(>>)
和(>>=)
的调用。
GHC使用启发式方法来确定要内联的内容,以获得最佳的运行时性能。它通常会内联非递归的小表达式。我相信运行时系统会维护当前正在评估的函数的调用堆栈,这与使用C或其他命令性语言编译函数调用的运行时结果相同。
GHC提供了many options for printing intermediate stages of compilation。我不确定您会发现哪个有趣。核心是感觉像Haskell的最低级别的表示形式。 Cmm(也称为C--)是感觉像汇编的最高级别表示。