"理性"一词在计算机科学中意味着什么?

use*_*976 48 haskell functional-programming scala

在学习函数式编程的过程中,我不断遇到"理由"一词,特别是在纯函数和/或引用透明性的背景下.有人可以解释一下究竟是什么意思吗?

Jak*_*mpl 45

通常在编写程序时,您的工作不仅仅是编写代码,而且您还需要了解代码所展示的某些属性.您可以通过两种方式到达这些属性:通过逻辑分析或通过经验观察.

此类属性的示例包括:

  • 正确性(程序是否按预期执行)
  • 表现(需要多长时间)
  • 可伸缩性(性能如何受输入影响)
  • 安全性(算法可以被恶意滥用)

根据经验测量这些属性时,会得到精度有限的结果.因此,从数学角度证明这些特性是非常优越的,但并不总是那么容易.功能语言通常具有其设计目标之一,使其属性的数学证明更易于处理.这通常是通过推理程序来实现的.


在功能或较小单元方面,以上适用,但有时作者仅仅意味着考虑算法或设计算法.这取决于具体用途.


另外,还有一些例子说明了如何推理这些事情以及如何进行经验观察:

正确性:我们可以证明代码是正确的,如果我们能够公平地表明它做了它应该做的事情.因此,对于排序函数,如果我们可以显示我们给它的任何列表将具有被排序的属性,我们知道我们的代码是正确的.根据经验,我们可以创建一个单元测试套件,在其中我们提供输入的代码示例并检查代码是否具有所需的输出.

性能和可伸缩性:我们可以分析我们的代码并证明算法的性能界限,以便我们知道它所花费的时间取决于输入的大小.根据经验,我们可以对代码进行基准测试,看看它在特定机器上实际运行的速度有多快.我们可以执行负载测试,并查看我们的机器/算法在折叠/变得不切实际之前可以获得多少实际输入.

  • 对于这四个类别,经验主义意味着:1.让QA找到错误.2.让友好的用户抱怨.3.让你的IT人员在服务器崩溃后凌晨3点给你打电话.4.将您的数据和服务器捐赠给不友好的用户.任何这些方法都意味着您的工作以编写代码结束.在这种情况下,你的老板会说,"Lemme告诉你为什么我会解雇你的原因." 正如他所说,他可能无意中吐了出来. (10认同)

kqr*_*kqr 23

对代码的推理,在最松散的意义上,意味着考虑你的代码及其真正的作用(不是你认为应该做的.)这意味着

  • 了解代码在向其投放数据时的行为方式,
  • 知道什么东西可以重构而不会破坏它,并且
  • 保持对标签有什么方法可以进行最佳化,

除其他事项外.对我来说,推理部分在我调试或重构时扮演着最重要的角色.

使用你提到的一个例子:当我试图弄清楚函数有什么问题时,参考透明度对我有很大的帮助.引用透明性保证当我在使用函数时,给它不同的参数,我知道函数将在我的程序中以相同的方式作出反应.它不依赖于其参数以外的任何东西.这使得函数更容易推理 - 而不是命令式语言,其中函数可能依赖于可能在我的鼻子下改变的一些外部变量.

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

map f (map g xs) === map (f . g) xs
Run Code Online (Sandbox Code Playgroud)

这是一个有用的属性,我可以直接在我重构时应用.我可以陈述Haskell代码的这些属性的事实使得更容易推理.我可以尝试在Python程序中声明这个属性,但是我对它的信心要小得多,因为如果我选择的时候运气不好f而且g结果可能会有很大不同.


Joh*_*ley 14

非正式地意味着,"能够通过查看代码来告诉程序将会做什么." 由于副作用,转换,隐式转换,重载函数和运算符等原因,这在大多数语言中都会出乎意料地难以实现.也就是说,当你不能仅使用你的大脑推理代码时,你必须运行它来查看是什么它会为给定的输入做.


Gab*_*lez 12

Usually when people say "reasoning" they mean "equational reasoning", which means proving properties about your code without ever running it.

These properties can be very simple. For example, given the following definition of (.) and id:

id :: a -> a
id x = x

(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) = \x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

... we might then want to prove that:

f . id = f
Run Code Online (Sandbox Code Playgroud)

This is easy to prove because:

(f . id) = \x -> f (id x) = \x -> f x = f
Run Code Online (Sandbox Code Playgroud)

Notice how I've proven this for all f. This means that I know that this property is always true no matter what, therefore I no longer need to test this property in some sort of unit test suite because I know that it can never fail.


npo*_*cop 9

"关于程序的推理"只是"分析程序以查看它的作用".

这个想法是纯度简化了理解,既可以通过人工改变程序,也可以通过机器编译程序或分析它来处理破碎的角落情况.