一些函数式编程构造是否会降低可调性?

时间:2009-12-12 20:40:54

标签: debugging functional-programming

我听说以下功能会降低可调试性(因为它们是匿名的,调试器无法很好地跟踪它)

  1. 匿名课程
  2. 内部课程
  3. Closures Blocks / Lambda函数
  4. 这是真的吗?

5 个答案:

答案 0 :(得分:7)

关于您提出的特定功能,已经有一些很好的答案。

一般来说,我会说一些FP功能,以及更多FP风格的编程方面,至少与调试体验“互动”。例如,使用高阶函数,可以以无点样式编程。当您这样做时,这会留下更少的标识符,这意味着例如在调试器的“本地”窗口中可以轻松检查的事物更少。在您进入他们的身体之前,闭包通常是不透明的。

FP还使用了大量的反转控制结构(懒惰的评估只是一个,'地图'或'iter'而不是'foreach'是另一个),这改变了控制流程并且可以影响'单一 - 步骤'工作。

随着FP变得越来越普遍,我希望调试工具能够继续改进。我不清楚某些FP是否“固有地”更难以调试,但即使这是真的,也不要忘记FP会让你的代码首先不太可能需要调试。 :)

答案 1 :(得分:2)

很难说它们是否固有地降低了可调试性。如果匿名函数抛出异常,您仍然可以打印堆栈跟踪。当事情发生时,DrScheme设法在代码中绘制红色箭头,以表示堆栈跟踪,并且处理匿名函数就好了。但是,调试像Scheme或Haskell这样的语言并没有那么多,就像用Eclipse一样进入Java,所以当然调试工具可能更糟。

而且,正如JaredPar所说,Visual Studio似乎在这方面和C#做得很好。

答案 2 :(得分:1)

我想说这绝对是不真实的。是的,如果没有额外的调试支持,这些结构可能会更难调试。在许多语言中,它们并不是真正的匿名,因为调试器不理解语言语义。相反,它理解程序的最终形式(.exe和PDB组合)。大多数匿名构造最终在最终程序中采用具体形式(对于.Net实现来说非常正确)。

此外,实现这些功能的语言通常会花时间为它们实现更好的调试支持。以C#和VB为例

  1. 两种语言都添加DebuggerDisplay属性并覆盖匿名的.ToString类型,生成以增加调试支持。实现有所不同,但结果几乎相同。
  2. 内部类在调试方面不是很特别,如果有任何额外的工作则不需要太多
  3. VB和C#在Visual Studio 2008中花费了大量时间来“展开”lambda表达式,并将捕获的自由变量显示为原始本地列表的一部分。使调试功能更容易

答案 3 :(得分:1)

您列出的功能不应该导致设计用于处理它们的调试器出现问题。如果您的调试器假定您将调试与C基本没有太大区别的东西,那么您可能会遇到问题。

现在,在函数式语言中更常见的一个功能是 导致调试器的麻烦,大量使用延迟评估。 Haskell在这方面特别成问题。

答案 4 :(得分:0)

从我的角度来看,我并不特别相信这种情况。我正在使用Scala的功能特性,它可以编译为在Java虚拟机上运行。像Intellij这样的调试器可以正常使用它。

话虽如此,一些代码构造以与您通常期望的方式不同的方式呈现。功能块在某些情况下显示为内部类。列表显示为头部实体加尾部列表(或者它可能是另一种方式 - 我刚刚开始使用它!)。