什么是声明式编程?

时间:2020-03-06 14:41:13  来源:igfitidea点击:

我一直在几个不同的背景下听到这个词。它是什么?

解决方案

声明式编程是指我们以编写代码的方式描述我们要执行的操作,而不是我们要执行的操作。由编译器来决定如何做。

声明性编程语言的示例是SQL和Prolog。

这是一种基于描述某件事应该做什么或者应该做什么而不是描述它应该如何工作的编程方法。

换句话说,我们不会编写由表达式构成的算法,而只是布局想要的事物。 HTML和WPF是两个很好的例子。

这篇Wikipedia文章是一个很好的概述:http://en.wikipedia.org/wiki/Declarative_programming

声明式编程是图片,其中命令式编程是绘制该图片的指令。

如果要"说明它是什么",则是以声明性的方式编写的,而不是描述计算机到达所需位置所应采取的步骤。

当我们使用XML标记数据时,我们使用的是声明式编程,因为我们在说"这是一个人,那是生日,在那儿有一条街道地址"。

将声明式和命令式编程结合在一起以产生更大效果的一些示例:

  • Windows Presentation Foundation使用声明性XML语法来描述用户界面的外观以及控件与基础数据结构之间的关系(绑定)。
  • 结构化配置文件使用声明性语法(如"键=值"对那样简单)来标识数据的字符串或者值的含义。
  • HTML用标记来标记文本,标记描述每个文本相对于整个文档所起的作用。

声明式编程的其他两个示例:

  • 用于数据绑定的ASP.Net标记。例如,它只是说"用此源填充此网格",然后将其留给系统以了解如何发生。
  • Linq表达式

声明式编程之所以不错,是因为它可以帮助简化思维模型*,并且最终可能具有更大的可扩展性。

例如,假设我们有一个函数会对数组或者列表中的每个元素执行某些操作。传统代码如下所示:

foreach (object item in MyList)
{
   DoSomething(item);
}

没什么大不了的。但是,如果我们使用更具声明性的语法,而是将DoSomething()定义为Action,该怎么办?然后我们可以这样说:

MyList.ForEach(DoSometing);

当然,这更加简洁。但是我敢肯定,除了在这里和那里保存两行代码外,我们还有更多的担忧。性能,例如。旧方法必须按顺序进行处理。如果.ForEach()方法可以让我们发信号通知它可以自动并行处理,该怎么办?现在突然之间,我们以一种非常安全的方式使代码成为多线程代码,并且只更改了一行代码。而且,实际上,.Net有一个扩展名,可以让我们做到这一点。

  • 如果我们点击该链接,它将带我们到我的一个朋友的博客文章中。整个帖子有点长,但是我们可以向下滚动到标题为"问题"的标题_并在那里找到它。*

向计算机描述我们想要的东西,而不是如何做某事。

据我所知,它开始被用来描述像Prolog这样的编程系统,因为prolog(据说)是关于以抽象的方式声明事物。

它的含义越来越小,因为它具有上述用户给出的定义。应该清楚的是,Haskell的声明式编程与HTML的声明式编程之间存在鸿沟。

想象一个excel页面。使用公式填充列以计算纳税申报单。

所有逻辑都在单元格中声明,计算顺序由公式本身确定,而不是程序确定。

这就是声明式编程的全部意义所在。我们声明问题空间和解决方案,而不是程序流程。

Prolog是我使用的唯一声明性语言。它需要不同的思维方式,但是最好学习是否让我们接触到典型的过程编程语言之外的其他东西。

其他答案已经很好地解释了声明式编程是什么,所以我将提供一些示例,说明为什么这样做可能有用。

声明式程序与上下文无关。因为它们仅声明最终目标是什么,而没有声明达到该目标的中间步骤,所以同一程序可以在不同的上下文中使用。使用命令式程序很难做到这一点,因为命令式程序通常取决于上下文(例如,隐藏状态)。

以" yacc"为例。这是一个解析器生成器。编译器编译器,一种用于描述语言语法的外部声明性DSL,以便可以从描述中自动生成该语言的解析器。由于其上下文无关性,我们可以使用这种语法来做许多不同的事情:

  • 为该语法生成​​一个C解析器(yacc的原始用例)
  • 为该语法生成​​C ++解析器
  • 为该语法生成​​Java解析器(使用Jay)
  • 为该语法生成​​C#解析器(使用GPPG)
  • 为该语法生成​​一个Ruby解析器(使用Racc)
  • 生成该语法的树形可视化文件(使用GraphViz)
  • 只需对yacc源文件本身进行漂亮的打印,精美的格式设置和语法高亮显示,并将其作为语言的语法规范包含在《参考手册》中

还有很多

因为我们没有规定计算机要采取什么步骤以及按照什么顺序进行操作,所以它可以更加自由地重新安排程序,甚至可以并行执行某些任务。一个很好的例子是用于SQL数据库的查询计划器和查询优化器。大多数SQL数据库允许我们显示它们实际执行的查询与我们要求它们执行的查询。通常,这些查询看起来互不相同。查询计划程序考虑了我们甚至梦dream以求的事情:例如磁盘磁盘的旋转等待时间,或者某个完全不同的用户的某些完全不同的应用程序刚刚执行了类似的查询,而我们却与一起努力,我们为避免加载而付出了辛勤的工作,无论如何它已经在内存中了。

这里有一个有趣的折衷:机器必须比用命令式语言更努力地找出如何做某事,但是当它找出来时,它具有更多的自由度和更多的优化信息阶段。

我会解释一下,因为DP是一种表达方式

  • 目标表达,即我们正在寻找的条件。有一个,也许一个或者多个?
  • 一些已知事实
  • 扩展已知事实的规则

...以及哪里有一个推演引擎,通常使用统一算法来找到目标。

听起来有些奇怪,但是我将Excel(或者任何电子表格)添加到声明性系统列表中。这是一个很好的例子。