我正在尝试自我学习SML
。虽然我可以写一些SML代码,但我还没有达到啊哈。
在:
val x = 5;
如何将value
5绑定到 name x
与在命令式编程中将值5分配给内存位置/变量x
不同?
我必须抛弃强制性编程才能快速赶上FP?
请对我温柔。
答案 0 :(得分:2)
在命令式编程中,如何将值5绑定到名称
x
与将值5分配给内存位置/变量x
不同?
函数式编程中的变量与命令式编程中的变量之间的关键区别在于函数式编程中的变量无法修改。
函数式编程语言中的变量在您可以修改其值的意义上不会发生变化。然而,它们在数学意义上的确有所不同,因为它们代表了一些未知的常数值。例如,请考虑以下二次表达式:
这是一个变量中的二次表达式。变量x
在您可以为x
选择任何值的意义上有所不同。但是,为x
选择某个值后,您无法更改该值。
现在,如果你有一个四元方程,那么x
的选择不再是任意的。例如,考虑以下二次方程:
x
的唯一选择是满足等式的选项(即x = -2
或x = -1.5
)。
另一方面,数学函数是两组之间的关系,称为域(输入集)和密码域(输出集)。例如,请考虑以下函数:
此函数将属于该组实数的x
与其对应的2x^2 + 7x + 6
相关联,该x
也属于该组实数。同样,我们可以自由选择x
的任何值。但是,一旦我们为val x = 5;
选择了一些值,我们就不允许对其进行修改。
关键在于它们被称为变量,因为它们在数学意义上有所不同,它们可以采用不同的值。因此,它们随实例而变化。但是,它们不随时间变化。
变量的这种不变性在函数式编程中很重要,因为它使你的程序referentially transparent(即调用函数可以被认为只是用函数体替换函数调用)。
如果允许变量随时间变化,那么您将无法简单地将函数调用替换为函数体,因为替换变量可能随时间而变化。因此,您的替代函数体可能会随着时间的推移而变得无效。
上述表达如何阐明"一种将计算视为数学函数评估并避免改变状态和可变数据的风格"?
表达式(fn x => y) 5
可以被认为是函数应用程序y
,其中{{1}}是程序的其余部分。函数式编程完全是关于函数和变量的,因为变量只是随实例而不是时间而变化。
特别是,可变性被认为是错误的,因为它是隐含的。任何隐含的东西都可能导致程序中出现无法预料的错误。因此,Zen of Python明确指出:
明确比隐含更好。
事实上,可变状态是primary cause of software complexity。因此,函数式编程试图尽可能地避免可变性。但是,这并不意味着我们只使用不可变结构。我们可以使用可变结构。我们只需要明确它。
我必须抛弃强制性编程才能快速赶上FP?
无。函数式编程和命令式编程是思考计算的两种方式。计算是一个非常抽象的想法。什么是计算?我们如何知道可以计算出哪些问题?这些是数学家在19世纪初期遇到的一些问题。
考虑计算,我们需要有一个正式的计算模型(即一个捕获计算概念的正式系统)。有各种各样的计算模型。然而,最着名的是lambda演算(它产生了函数式编程)和图灵机(它引发了命令式编程)。
lambda演算和图灵机都具有相同的功率。它们都捕获了计算的概念,并且可以计算的每个问题都可以表示为lambda演算表达式或等效的图灵机。唯一的区别是你表达问题的方式。
您不必丢弃任何有关命令式编程的知识,以了解函数式编程。两者都不比另一个好。它们只是表达同一问题的不同方式。但是,你需要开始像功能程序员一样思考编写好的功能程序。