“我只是有点困惑它是否是纯函数式的,因为它似乎主要用于数学函数”
这似乎是对“纯函数”一词含义的误解,也可能是对“数学函数”一词含义的误解。
数学函数
mathematical function 是输入和输出之间的映射:
在数学中,函数是集合之间的关系,它与第一个集合的每个元素恰好关联到第二个集合的一个元素。
在编程语言的上下文中,函数的输入是它的参数,输出是它的返回值,例如像
这样的函数
def greeting(name):
return 'Hello, ' + name
在 Python 中被认为是一个数学函数,而类似的函数
def print_square(x):
print(x ** 2)
return None
不被视为数学函数。请注意,计算本质上是否是数学计算与它是否是数学意义上的函数无关。 print_square 做了一些算术运算,这比greeting 做的更像数学。但是greeting 是一个数学函数,而print_square 不是。
greeting 是一个数学函数,因为它是从字符串集合到字符串集合的映射,并且该函数可以通过哪些输入与哪些输出相关联来描述。完整地写出映射需要无限多行,但映射如下:
'Alice' → 'Hello, Alice'
'Bob' → 'Hello, Bob'
'Charles' → 'Hello, Charles'
'####' → 'Hello, ####'
'' → 'Hello, '
...
第一个集合(即所有字符串的集合)中的每个元素都与第二个集合中的一个元素相关联,因此greeting 符合数学函数的定义。
相比之下,print_square 不是一个数学函数,因为它不能通过从输入到输出的映射来描述:
12 → None
4 → None
...
这些映射(从整数集到 {None} 集)没有正确定义 print_square 的作用,即它计算输入和 prints it to the console 的平方。
为避免与“执行数学运算的函数”混淆,最好使用计算术语“pure function”:
...纯函数是数学函数的计算模拟。
因此,为了解决您对 Fortran “似乎主要用于数学函数” 的评论,Fortran 主要用于进行数学计算,但这不是“数学函数”的意思。
纯函数式编程
purely functional 编程语言是一种所有计算都由纯函数完成的语言:
在计算机科学中,纯函数式编程通常指定一种编程范式……将所有计算视为对数学函数的评估。纯函数式编程也可以通过禁止更改状态和可变数据来定义。
请注意,编程语言允许您编写纯函数是不够的;该定义表明,所有计算必须由纯函数完成,该语言才有资格成为纯函数。
Fortran 是纯函数式语言吗?不它不是。 Fortran 中的子程序可以根据输入和输出之间的映射做除了返回值之外的事情; Fortran 中的计算可以通过状态更改和可变数据来完成。一个例子就足够了:这个来自Rosetta Code。
subroutine hs(number, length, seqArray)
integer, intent(in) :: number
integer, intent(out) :: length
integer, optional, intent(inout) :: seqArray(:)
integer :: n
n = number
length = 1
if(present(seqArray)) seqArray(1) = n
do while(n /= 1)
if(mod(n,2) == 0) then
n = n / 2
else
n = n * 3 + 1
end if
length = length + 1
if(present(seqArray)) seqArray(length) = n
end do
end subroutine
变量n 显然是可变的,因为它的状态在循环中改变。此外,数组seqArray 是可变的,它既是子例程的输入和输出,子例程会更改数组的状态。所以这个子程序没有定义一个纯函数,它使用了“改变状态和可变数据”,这是纯函数语言的定义所禁止的。
所以子程序hs 没有定义“数学函数”,即使它执行的计算本质上是mathematical。
命令式编程
Imperative programming 是:
... 一种编程范式,它使用改变程序状态的语句。 ...命令式程序由计算机执行的命令组成。
上面显示的 Fortran 子例程满足这两个定义:它使用语句或命令来改变计算机执行的程序状态。所以 Fortran 是一种命令式编程语言。
请注意,与 Wikipedia 对“纯函数式”的定义不同,一种语言可以是命令式的,即使它不以这种方式进行所有计算。因此,虽然可能在 Fortran 中编写不能通过更改程序状态来工作的纯函数,但 Fortran 是必不可少的;只是也许不是“绝对必要的”。
“什么”与“如何”
“这意味着 fortran 只描述了‘如何’做某事而不是‘它试图做什么’?”
人们常说,命令式程序是说“如何”进行计算的程序,而声明式程序只说“应该做什么”。连维基百科says so:
命令式编程侧重于描述如何程序运行。
该术语通常用于与声明式编程形成对比,声明式编程侧重于程序应该完成什么,而不指定程序应该如何实现结果。
那么描述程序应该“如何”做某事或应该完成“什么”的 Fortran 代码也是如此吗?
像n = n / 2 这样的语句是告诉计算机做某事的命令;在计算机执行命令之前有一个程序状态,之后有一个不同的程序状态。语句n = n / 2 还告诉计算机“如何”执行命令:将n 的当前值除以2,并将结果存储在变量n 中。所以根据“how”/“what”的区别,Fortran是命令式的,而不是声明式的。
但你可能会争辩:n = n / 2 说的是我们想要实现的“什么”;一个新的程序状态,n 保留旧状态的值,除以 2。你是对的,它确实这么说,至少对于阅读它的人来说。
这表明“如何”/“什么”的区别过于模糊,无法用作决定语言是命令式还是声明式的定义。它的意思是这些范式之间的松散描述的对比,而不是对任何一个范式的定义。要确定一种语言是命令式的还是纯函数式的,或者在任何其他范式中,您应该参考该范式的可服务定义。