之间的区别是什么声明性和必要的编程?[关闭]
-
21-09-2019 - |
题
我已经搜索网络寻找一个定义对于明性和必要的方案,将阐明一些我。然而,所使用的语言的一些资源,我们发现是艰巨的,例如在 维基百科.没有任何人有一个真实世界的例子,他们可以告诉我可能会带来一些透到这个问题(也许在C#)?
解决方案
一个伟大的C#例的声明与必须编程是皇宫.
与 势在必行 编程中,你告诉compiler你想会发生什么,一步步骤。
例如,让我们开始与这个集合,并选择的奇数字:
List<int> collection = new List<int> { 1, 2, 3, 4, 5 };
与必须编程,我们逐步通过这一点,并决定我们想要的:
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
在这里,我们说:
- 创建此集合
- 步骤,通过每个数字的收集
- 检查号码,如果是奇怪的,将它添加到结果
与 声明 编程,另一方面,编写代码,介绍了什么是你想要的,但不一定是如何得到它(宣布你所希望的结果,但不一步一步):
var results = collection.Where( num => num % 2 != 0);
在这里,我们说"给我们一切都在哪里很奇怪",不是"步骤,通过收集。检查这个项目,如果这是奇怪的,将它添加到一个结果收集"。
在许多情况下,代码将两者混合物的设计中,也是如此,所以它并不总是黑色和白色。
其他提示
声明性编程是当你说的什么的你想要的,命令式语言是当你说的如何的得到你想要的东西。
Python中的简单示例:
# Declarative
small_nums = [x for x in range(20) if x < 5]
# Imperative
small_nums = []
for i in range(20):
if i < 5:
small_nums.append(i)
在第一个例子是声明,因为我们没有指定建筑列表中的任何“实施细则”。
要配合C#的例子,一般来说,使用了声明式的LINQ的结果,因为你是不是说的如何的获得你想要的东西;你只说的 的你想要什么。你可以说,有关SQL相同。
声明式编程的一个好处是,它允许编译器做出可能导致更好的代码可能比你的手做出什么样的决定。与SQL例如跑步,如果你有一个像查询
SELECT score FROM games WHERE id < 100;
的SQL“编译”能够“优化”这个查询因为它知道id
是一个索引字段 - 或者它不被索引,在这种情况下它必须遍历整个数据集无论如何。或者,也许SQL引擎知道这是利用所有8个内核的快速并行搜索的最佳时机。的您的,作为一个程序员,不关心任何这些条件,你不必编写代码来处理这样的任何特殊情况。
声明与祈使
一个编程范式是计算机编程的一个基本样式。 有四种主要的范例:势在必行,声明性,功能性(这被认为是声明性范例的子集)和面向对象的
声明性编程:是一种编程范式,表达计算(做什么)的逻辑,而不描述其控制流(如何做)。 声明领域特定语言(DSL)的一些著名的例子包括CSS,正则表达式和SQL的一个子集(SELECT查询,例如) 许多标记语言如HTML,MXML,XAML,XSLT ......常常声明。 所述声明性编程尝试模糊的程序之间的区别为一组的指令和程序作为关于期望答案的断言。
命令式编程:是描述在改变一个程序状态的语句而言计算的编程范例。声明性程序可以双重视为编程命令或数学断言。
功能编程:是一种编程范例,治疗计算为数学函数,并且避免了状态和可变数据的评估。它强调的功能的应用,在对比的是命令式编程风格,它强调的状态变化。 在纯功能性的语言,如Haskell中,所有功能都没有副作用,和状态改变仅表示为变换的状态的功能。
命令性编程的在 MSDN 一个下面的示例>,循环通过数字1到10,并查找偶数。
var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{ if (number % 2 == 0)
{
evenNumbers.Add(number);
}
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);
两个例子都产生相同的结果,并且一个既不是更好,也不比另一个差。第一个例子需要更多的代码,但是代码是可测试,以及必要的方法让您的实现细节的完全控制。在第二个例子中,代码可以说是更易读;然而,LINQ不给你控制在幕后发生了什么。你必须相信,LINQ将提供所要求的结果。
我将添加另一个例子是,在声明/命令式编程讨论很少弹出:用户界面
在C#,可以构建使用各种技术的UI。
在祈使句末尾,你可以使用DirectX或OpenGL非常势在必行请你按钮,复选框,等...行由行(或真的,由三角形三角形)。它是由你说如何绘制用户界面。
目前声明结束时,必须WPF。你基本上写一些XML(耶,耶,“XAML”技术上)和框架做的工作适合你。你说什么用户界面的样子。它是由该系统找出如何做到这一点。
总之,只要还有一点要思考的问题。仅仅因为一种语言是声明性或命令并不意味着它没有其他的某些功能。
另外,声明性编程的一个好处是,目的通常是更容易理解从阅读代码而必须让你在执行更精细的控制。
它的所有的要点:
声明 - > what
你想要做
势在必行 - >你想how
它做
所有上述答复以及其他在线职位说下面的:
- 与 声明 编程,编写代码,介绍了什么是你想要的,但不一定是如何得到它
- 你应该喜欢的说明性程序通过必要的编程
他们有什么不告诉我们 如何去实现它.对于程序的一部分应更声明,其他部分必须 提供的抽象 隐藏的执行情况的详细信息(这是 势在必行 代码)。
- E.g., 皇宫是更多的声明于循环(为,同时,等等), 例如,可以使用
list.Where()
得到一个新的过滤清单。对于这项工作,微软已经做了所有的繁重工作背后的皇宫的抽象概念。
事实上,其中一个原因编程功能和功能的图书馆是更多的声明是因为他们有抽象的距离循环和列表的作品,隐藏的所有执行情况的详细信息(最有可能必须码循环)的背后的现场。
在任何程序中,总是会有两个必要和声明的代码,你应该瞄准什么是隐藏的所有 势在必行 代码后面的抽象概念,以使该程序的其他部分可以使用它们 以声明方式.
最后,虽然编程功能和皇宫可以做你的节目更多的宣示性的,你总是可以使它更说明性通过提供更多的抽象概念。例如:
// JavaScript example
// Least declarative
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
let product = products[i];
if (product.rating >= 5 && product.price < 100) {
bestProducts.push(product);
}
}
// More declarative
const bestProducts = products.filter(function(product) {
return product.rating >= 5 && product.price < 100;
});
// Most declarative, implementation details are hidden in a function
const bestProducts = getBestProducts();
我喜欢一个说明从一个剑桥课程+他们的例子:
- 声明 -指定 什么样的 要做, 不如何 要做到这
- E.g.:HTML描述了什么应该出现在网页上,而不是如何应该在屏幕上绘制
- 势在必行 -指定 什么样的 和 如何
int x;
-什么样的(说明性)x=x+1;
-怎么
必须编程,需要商定一步一步如何 代码应加以执行。得到的方向,在必要的时尚, 你说,"去第1条街左转到主要驱动两个区块, 右转到枫树,并停止在三楼左侧。" 的 声明的版本听起来可能像这样的东西:"驱起诉的 房子。" 一个说,如何做到的东西;其他说什么需要 完成。
该声明风格有两个优点在必要的风格:
- 它没有迫使旅行者的记忆一个长期设置的说明。
- 它允许旅行者优化的途径,在可能的情况。
卡尔弗特,C Kulkarni,D(2009年)。重要的皇宫.Addison Wesley.48.
差别主要与的总体水平的抽象概念。与声明,在某些时候,你是那么远从各个步骤,该程序有一个很大的纬度关于如何得到你的结果。
你可以看着每一条指令为落的地方在一个连续:
程度的抽象:
Declarative <<=====|==================>> Imperative
声明的真实世界的例子:
- 图书管理员,请我进行检查的副本Moby Dick.(图书管理员,在他们的自由裁量权选择最佳方法执行该请求)
必须现实世界的例子:
- 进入图书馆
- 找书的组织系统(卡片目录-老学校)
- 研究如何使用卡片目录(你忘了,对)
- 找出如何货架上都标记和组织。
- 图书是有组织的架子上。
- 交叉参考书中的位置,从卡片目录的组织系统,以查找上述书。
- 把书退房系统。
- 检查出书。
命令式编程是告诉计算机明确做什么,以及如何做到这一点,如指定顺序和这样
C#:
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Hello World!");
}
声明是当你告诉计算机做什么,但没有真正如何做到这一点。数据记录/ Prolog是,想到了这方面的第一语言。基本上一切声明。你不能真正保证秩序。
C#是一个更命令式编程语言,但某些C#特征更声明性的,像LINQ的
dynamic foo = from c in someCollection
let x = someValue * 2
where c.SomeProperty < x
select new {c.SomeProperty, c.OtherProperty};
同样的事情可以势在必行写成:
dynamic foo = SomeCollection.Where
(
c => c.SomeProperty < (SomeValue * 2)
)
.Select
(
c => new {c.SomeProperty, c.OtherProperty}
)
(例如,从维基百科LINQ)
在计算机科学中,声明性编程是表达一个计算的逻辑,而不描述其控制流程的编程范例。
从 http://en.wikipedia.org/wiki/Declarative_programming
简而言之的声明性语言是简单的,因为它缺少的控制流程(循环,if语句等)
的复杂性一个很好的比较是ASP.Net“代码隐藏”的模式。你必须声明“.ASPX”文件,然后在必要‘ASPX.CS’代码文件。我常常觉得,如果我可以做所有我需要在脚本的声明一半有更多的人可以按照什么正在做。
偷窃 菲利普*罗伯茨在这里:
- 必须告诉程的机如何做(造成什么是你希望发生的事情)
- 说明性程序告诉机器什么你希望发生的(和计算机数字如何做到这一)
两个例子:
1.增加一倍的所有数字阵列
强制:
var numbers = [1,2,3,4,5]
var doubled = []
for(var i = 0; i < numbers.length; i++) {
var newNumber = numbers[i] * 2
doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
以声明的方式:
var numbers = [1,2,3,4,5]
var doubled = numbers.map(function(n) {
return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
2.总结所有项目列表中的
强制
var numbers = [1,2,3,4,5]
var total = 0
for(var i = 0; i < numbers.length; i++) {
total += numbers[i]
}
console.log(total) //=> 15
以声明方式
var numbers = [1,2,3,4,5]
var total = numbers.reduce(function(sum, n) {
return sum + n
});
console.log(total) //=> 15
注意如何必须实例涉及到创建一个新的变量,改变它,并返回,新的价值(即,如何使事情发生),而该声明的实例执行上给出的输入和返回的新的价值基于最初输入(即,我们想要发生)。
只需添加在移动应用程序开发方面的另一个例子。在IOS和Android我们有接口助洗剂,在这里我们可以定义应用程序的UI。
使用这些助洗剂在本质上,在那里我们拖放组件声明性绘制的UI。实际draeing偏偏下方并且由所述框架和系统进行。
但是,我们也可以得出在整个代码的组件,且在本质上是必要的。
此外,像角JS一些新的语言是集中于声明用户界面设计和我们可能会看到很多其他语言提供同样的支持。像Java多年平均值有什么好的声明的方式来绘制的Java Swing或Java FX,但在不久的将来,本地桌面应用程序,他们只是可能。
声明性程序仅仅是其一些更多或更少的“通用”实施势在必行/ VM数据。
加号: 仅指定一个数据,在一些硬编码(和检查)格式,更简单并且比直接指定一些势在必行算法的变体容易出错较少。一些复杂的规范只是不能被直接写入,只能在一些DSL形式。 最好和DSL的数据结构中所用频率是集和表。因为你没有元素/行之间的依赖关系。当你还没有依赖关系,你能自由地修改和简化的支持。 (比较与类模块为例 - 与模块你快乐,并与类你有脆弱的基类问题) declarativeness和DSL的所有商品从数据结构(表和套)的收益紧随其后。 另外再加上 - 你可以改变执行说明性语言虚拟机,如果DSL是更多或更少的抽象(精心设计)。使并行执行,例如。或它移植到其他OS等等都好specifed模块化隔离接口或协议给你这种自由和支持easyness。
弊: 你猜对了。通用的(和由DSL参数)势在必行算法/ VM实现可以比特定的一个更慢和/或存储器饿。在某些情况下。 如果情况是罕见的 - 忘掉它,让它缓慢。如果是frequient - 你总是可以延长你的DSL / VM的这种情况下。地方放慢所有其他情况下,确定...
P.S。框架是DSL和势在必行之间的一半。和所有中途的解决方案......他们结合deficiences,没有好处。他们不那么安全,不会这么快:)看看千斤顶的,全行业的Haskell - 它的一半强简单ML和灵活metaprog序言和...这是什么怪物之间。你可以看看序言作为一个Haskell只布尔函数/谓词。和它的灵活性是多么简单针对的Haskell ...
我只是想知道为什么没有人提到属性类在C#中的声明性编程工具。此页面的普遍的回答刚才谈到LINQ的声明性编程工具。
根据维基百科
普通的声明性语言包括那些数据库查询语言的 (例如,SQL和XQuery),正则表达式,逻辑编程, 函数编程,和配置管理系统。
因此LINQ,作为功能性语法,绝对是声明性的方法,但在C#属性的类,作为配置工具,是声明太。这里是一个很好的出发点,详细了解它:快速C#编程属性的概述
从我的理解,这两个词有根的理念,有声明和必要的各种知识。陈述性知识是真理的说法,其实喜欢数学的公理的陈述。它说 你的东西。当务之急,还是程序性知识,告诉你如何一步一步来的东西到达。这就是一个算法的定义本质上是。如果你愿意,比较计算机编程语言的英语。陈述句陈述的东西。的镗孔的例子,但这里是显示两个号是否彼此相等,在Java的声明性方式:
public static void main(String[] args)
{
System.out.print("4 = 4.");
}
祈使句在英语中,在另一方面,得到的命令或使某种请求。命令式编程,那么,仅仅是命令的列表(这样做,这样做)。下面是显示两个号是否彼此相等或不同时接受用户输入,在Java的命令式方式:
private static Scanner input;
public static void main(String[] args)
{
input = new Scanner(System.in);
System.out.println();
System.out.print("Enter an integer value for x: ");
int x = input.nextInt();
System.out.print("Enter an integer value for y: ");
int y = input.nextInt();
System.out.println();
System.out.printf("%d == %d? %s\n", x, y, x == y);
}
基本上,陈述性知识跳过某些元素,以形成抽象上的那些元件的层。声明性编程不相同。