数学函数和编程函数有什么区别?
答案 0 :(得分:22)
在函数式编程中,您有Referential Transparency,这意味着您可以在不更改程序的情况下将函数替换为其值。 这也是数学中的 true ,但在命令式语言中并非总是如此 。
数学函数定义为:将一个集合(A)中的元素映射到另一个集合(B)的关系,将第一个集合中的每个元素仅映射到另一个集合中的一个。 在C语言中(与其他编程语言一样),这也是正确的,您有输入集和输出集(几乎总是只有一个)。
主要区别在于,始终如果您在数学中调用f(x)
,您将获得相同的答案,但如果您在C中调用f'(x)
,答案可能不一样(相同的参数不会得到相同的输出)。(我认为这有点假。如果你有两个完全相同的机器状态,他们会输出相同的..但它试图说的是非函数语言中的函数可能不仅仅依赖于你给它们的参数,而是依赖于程序的其他东西)
数学和C函数之间的另一个区别是,在Math中,你不能创建一个从非空集到空集的函数(在C中,这将是:你不需要总是返回一些东西与你的功能)。此外,并非所有函数都是computable(我不知道数学中是否有类似的东西......)。你没有无限集的函数(你有有限的内存,所以可能的输入参数集必须是有限的),但在数学中,你可以为无限集定义一个函数(如f:N - > N)对于uncountable集(如f:R - > R)(在C中你有浮点数,但它们只代表一组简化的实数,这是有限的)。
最后,要知道函数式编程是最接近数学函数的函数,并且,您可以使用C作为函数式语言(或类似的东西)。查看"Functional C"
对不起,如果我的英语不好,希望我的回答可以帮到你。
<强>综述强>:
在C中,您并不总是具有参考透明度。对于相同的输入参数,您的函数可能并不总是给出相同的输出。您可以使用为无限输入集定义的Math函数,但在C函数中,您的输入是有限的。在C函数中,您可以使用不返回任何内容的函数,但在Math中您不能使用该函数(如果您的函数具有非空输入集,则必须使用另一个集合映射每个元素)。
答案 1 :(得分:6)
这取决于域名(我不是指函数的域名,我指的是研究领域),也可能是语言。
在数学中,函数的输入只映射到给定输入值的一个输出(垂直线测试,请记住)。在编程中,这可能不完全相同,这取决于您在“输入”和“函数逻辑”之间绘制线的位置。
例如,让我们假设我们有一个函数rand()来读取大气条件以得到一个真正的随机数。让我们假设一个调用函数将一个整数参数作为各种各样的多重参数。以下是函数吗?:
int giveRandAtmosWithMul(int mult)
{
return mult * rand();
}
在数学意义上,如果你认为mult是问题的唯一输入,它可能不是一个函数,但显然rand()也提供输入(即使rand()总是在机器中有相同的入口点码)。
正如您所看到的,如果没有每个人都同意的标准协议,差异就不能真正客观地定义。
答案 2 :(得分:3)
我认为最重要的区别是数学(和函数式编程)中的函数不能改变状态,而(命令式)编程函数可以。
答案 3 :(得分:2)
其他答案是正确的 - 这是两个不同的事情。相反,我会表明它们是相关的。我将->
表示编程函数,=>
表示数学函数。
假设您有一种支持例外的语言。在这种情况下,您可以将编程函数A -> B
视为数学函数A => B + E
,其中“B + E”表示B
类型的某种类型或{{1}类型的某种类型}。您的语言有两个关键字可以从函数返回,“return”和“throw”。
现在,您可以通过编写E
来撰写两个函数f: A -> B
和g: B -> C
。这是一个接受A并返回C的函数。您可以使用许多语言(如Java或Python)执行此操作。如果g(f(x))
引发异常,则不会调用f(x)
并传播异常 - 请考虑g
。该语言负责这一点,您无需检查g(1/0)
的结果是否异常。以数学方式描述的方法虽然是f
和f: A => B+E
,但语言将函数g“提升”为g: B => C+E
。 B+E => C+E
现在是一个可能会出现异常的函数,但它只会传播它。
换句话说,通过
定义g
g': B+E => C+E
有两个函数 / g(x) if x ∈ B
g'(x)= |
\ x if x ∈ E
和f: A => B+E
,您可以在数学意义上安全地编写它们。这就是编程中g': B+E => C+E
的作用,但必须先将g(f(x))
提升为g
。
考虑不确定性。如果你有一个不确定的函数g'
,那么你可以用数学方式描述它是一个函数A -> B
,其中A => Set(B)
是可能结果的集合。例如,如果Set(B)
可能会给你1,2或3,那么在数学上f(1)
虽然在编程时要求f(1) = {1,2,3}
,但您只能获得其中一个数字。现在,您可以通过编写f(1)
来撰写非确定性函数A->B
和B->C
。结果将是g(f(x))
类型,但它将是不确定的。在数学上,撰写函数C
和A => Set(B)
会为您提供B => Set(C)
。虽然A => Set(C)
只需要g
的一个值,但您必须将其提升为非确定性值B
。例如,g': Set(B) => Set(C)
是集合g'({1,2})
和g(1)
的并集。因此,g(2)
表示您运行g(f(x))
,获取所有可能结果的集合并在每个结果上运行f
。有两层不确定性,但它们被“扁平化”为一层。
与全球国家相同。如果将每个全局变量作为函数和结果的参数,则可以认为没有全局变量,每个函数都采用全局状态,语言在编写时必须移交状态。函数g
读取并可能写入状态A -> B
是函数S
,也可以写为(A,S) => (B,S)
。正式地写这个更复杂,但它是相同的模式。
输入/输出也是如此,我在另一个SO answer中描述了它。
允许组成“有效”功能的“魔力”是:
A => (S => (B,S))
转为B
或B+E
。我将Set(B)
类型的有效版本表示为X
。F(X)
进入B -> F(C)
。它允许撰写函数F(B) -> F(C)
和A -> F(B)
。B -> F(C)
必须将普通值return
变为A
或单A+E
。所以它的类型必须是Set(A)
。由这三者组成的结构称为monad。 Monads允许描述这些副作用。 monad也可能有一些特定的函数,例如,monad monad X -> F(X)
,nondeterminism monad有throw
,state monad有fork
,IO monad有get/put
等
道德是:如果你把特殊效果看作随机化,异常,非确定性,输入/输出作为函数结果的一部分,那么每个函数都是参考透明的,命令式编程中的函数实际上是数学函数,但是非常奇怪的结果类型也描述了特殊效果。这是像Haskell这样的纯函数式语言所采用的方法。
答案 4 :(得分:1)
数学函数本质上是声明性的,即它们总是具有“什么是”描述,而计算机科学中的函数是必要的,即它们具有“如何”描述。
参考:计算机程序的结构和解释。
答案 5 :(得分:0)
在数学中,函数不会抛出异常。 :)
计算机科学中的一个函数是一块代码,它接受输入,做某事并可能返回输出,但它可以在它们之间做很多事情。它可以获取网页,发送电子邮件,播放视频等等。
在数学中,函数是非常具体的,没有别的。功能通常被描述为接收输入和吐出输出的“机器”。虽然计算机科学函数确实接受输入并吐出输出,但它们不必这样做,精确的“相同的输入总是产生数学所需的相同输出”(例如,bool IsMyApplicationRunningInFullScreen()返回各种值而没有输入在所有)。