我知道声明性编程只是传递输入并期望输出而不说明程序是如何完成的。在函数式编程中,是一种编程范例,它接受输入并返回输出。当我检查高阶函数编程时,我们传递一个map / reduce函数,它没有透露程序是如何完成的。高阶函数式编程和声明性编程是一样的吗?
答案 0 :(得分:6)
简短回答:否。
维基百科将declarative programming定义为:
在计算机科学中,声明性编程是一种编程 范式 - 一种构建计算机结构和元素的方式 程序 - 表达计算的逻辑而不进行描述 其控制流程。
或者大胆地说:“说出你想要的,而不是你想要的。”。
因此,这与命令式编程语言形成对比,其中程序被视为一组接一个地完成的指令。 map
等没有透露过程这一事实并没有使它成为声明性:可以使用许多专有的C库,并且不允许您检查源代码。然而,这并不意味着这些都是声明性的。
另一方面,functional programming的定义是:
在计算机科学中,函数式编程是一种编程范式 - 一种构建计算机程序结构和元素的方式 - 将计算视为数学函数的评估,避免改变状态和可变数据。它是一个声明性的 编程范式,这意味着编程是通过表达式完成的 或声明而非声明。
基于这些定义,可以说函数式编程是声明式编程的子集。实际上,如果我们遵循严格定义,那么现在没有任何编程语言是纯粹的,非虚拟的声明性或功能性。然而,可以说 Haskell 声明比Java 更多。
声明性编程通常被认为是“更安全”,因为人们往往难以管理副作用。许多编程错误是不考虑所有副作用的结果。另一方面,很难
有几次尝试设计这种语言。最受欢迎的是 - 在我看来 - 逻辑编程,函数式编程和约束编程。每个都有其优点和问题。我们还可以在例如数据库(如SQL)和文本/ XML处理(使用 XSLT , XPath ,)中观察此声明性方法正则表达式,...)其中一个不指定查询的解析方式,但只是通过例如正则表达式来指定查找的内容。
编程语言是否具有声明性,是一种模糊的讨论。虽然编程语言,建模语言和库(如Haskell,Prolog,Gecode等)确实使编程更具说明性,但这些可能不是最严格意义上的声明。在大多数严格意义上,人们应该认为无论如何编写逻辑,编译器总会得到相同的结果(尽管可能需要更长的时间)
比如说我们要检查Haskell中的列表是否为空。我们可以这样写:
is_empty1 :: [a] -> Bool
is_empty1 [] = True
is_empty1 (_:_) = False
我们也可以这样写:
is_empty2 :: [a] -> Bool
is_empty2 l = length l == 0
两者都应该为相同的查询提供相同的结果。但是,如果我们给它一个无限列表,is_empty1 (repeat 0)
将返回False
,而is_empty2 (repeat 0)
将永远循环。所以这意味着我们仍然在程序中写了一些“控制流”:我们已经定义了 - 在某种程度上 - Haskell应该如何评估它。虽然延迟编程会导致程序员没有真正指定应该首先评估的内容,但仍然有规范Haskell如何评估它。
据一些人说,这是编程和指定之间的区别。我的一位教授曾经说过,根据他的不同,不同的是,当你编写某些东西时,你会以某种方式控制如何评估某些东西,而当你指定某事时,你无法控制。但同样,这只是许多定义的一个。
答案 1 :(得分:2)
不完全是,函数式编程更多地强调计算内容而不是计算方法。但是,函数式编程中存在一些模式,这些模式通常与声明性编程相关联的控制流模式,例如以下控制流程:
let continue = ref true in
while !continue do
...
if cond then continue := false
else
...
done
看起来很熟悉吧?在这里你可以看到一些声明性结构,但是这次我们可以更好地控制它。