计算机科学中的“reason about”是什么意思?

在学习函数式编程的同时,我还会遇到“纯粹的理由”一词,特别是在纯函数和/或参照透明性的背景下。 有人可以解释这到底是什么意思?

通常,在编写程序时,您的工作不仅仅是编写代码,而且还希望了解您的代码所展示的一些属性。 您可以通过两种方式来获得这些属性:通过逻辑分析或通过经验观察。

这些属性的例子包括:

  • 正确性(程序是否按照它应该做的那样)
  • 性能(需要多长时间)
  • 可伸缩性(性能如何影响input)
  • 安全(algorithm可以被恶意滥用)

当您凭经验测量这些属性时,会得到精度有限的结果。 因此,math上certificate这些性质是非常优越的,但是这并不总是容易的。 function语言通常具有其devise目标之一,使得其属性的mathcertificate更易于处理。 这是推理程序的典型意思。


在function上或者在较小的单元上,上面都是适用的,但是有时候作者仅仅意味着思考algorithm或者devisealgorithm。 这取决于具体的用法。


除此之外,还有一些例子说明了这些事情的一些原因,以及如何进行经验观察:

正确性:我们可以certificate代码是正确的,如果我们能够等价地表明它是做它应该做的。 所以对于一个sorting函数,如果我们可以显示任何我们给它的列表将有被sorting的属性,我们知道我们的代码是正确的。 经验上,我们可以创build一个unit testing套件,在这里我们给出我们的代码input示例,并检查代码是否具有期望的输出。

性能和可伸缩性:我们可以分析我们的代码,并certificatealgorithm的性能界限,以便我们知道如何花费时间取决于input的大小。 经验上,我们可以对我们的代码进行基准testing,看看它在特定机器上实际运行的速度。 我们可以进行负载testing,看看我们的机器/algorithm在折叠/变得不切实际前能够input多less实际的input。

从代码的angular度来讲,最简单的意思就是代码的思考,以及代码的真正含义(不是你认为它应该做什么)。这意味着

  • 当你把数据扔到你的代码时,意识到你的代码的行为方式
  • 知道你可以重构什么东西 ,而不会打破它
  • 密切关注可以执行哪些优化

除其他事项外。 对我来说,推理部分在debugging或重构时扮演着最重要的angular色。

使用你提到的一个例子:当我试图找出函数的错误时,引用透明度可以帮助我很多。 引用的透明性保证了当我在函数中使用不同的参数时,我知道这个函数在我的程序中会有同样的反应。 除了它的论点以外,它不依赖于其他任何东西。 这使得函数更容易推理 – 而不是命令式语言,函数可能依赖于可能在我鼻子下面改变的一些外部variables。

查看它的另一种方式(这在重构时更有用)是,越是知道代码满足某些特性,就越容易推理。 我知道,例如,那

map f (map g xs) === map (f . g) xs 

这是一个有用的属性,我可以直接应用,当我重构。 我可以声明Haskell代码的这个属性的事实使得更容易推理。 我可以尝试在Python程序中声明这个属性,但是我会更加不自信,因为如果我在selectfg的时候运气不好,结果可能会大不相同。

非正式的意思是,“只要看看代码,就能知道程序会做什么”。 在大多数语言中,由于副作用,投射,隐式转换,重载函数和运算符等,这可能会令人惊讶地困难。也就是说,当你无法仅仅用大脑推理代码时,就必须运行它来看看它会做一个给定的input。

通常当人们说“推理”时,他们的意思是“等同推理”,这意味着certificate你的代码的属性而不运行它。

这些属性可以非常简单。 例如,给出以下(.)id定义:

 id :: a -> a id x = x (.) :: (b -> c) -> (a -> b) -> (a -> c) (f . g) = \x -> f (gx) 

我们可能想要certificate:

 f . id = f 

这很容易certificate,因为:

 (f . id) = \x -> f (id x) = \x -> fx = f 

注意我是如何为所有的 fcertificate了这一点的。 这意味着我知道这个属性总是对的,不pipe怎么样,因此我不再需要在某种unit testing套件中testing这个属性,因为我知道它永远不会失败。

“推理一个程序”只是“分析一个程序,看看它是做什么的”。

这个想法是纯度简化了理解,无论是人为改变一个程序,还是一台机器编译一个程序,或者分析一个破碎的angular落案例。