Bra*_*rad 494 c# paradigms imperative-programming declarative-programming
我一直在网上寻找声明性和命令性编程的定义,这将为我提供一些启示.但是,我发现的一些资源中使用的语言令人生畏 - 例如在维基百科上.有没有人有一个现实世界的例子,他们可以告诉我可能会给这个主题带来一些看法(也许在C#中)?
Ree*_*sey 733
LINQ是声明性与命令式编程的一个很好的C#示例.
通过命令式编程,您可以逐步告诉编译器您想要发生什么.
例如,让我们从这个集合开始,然后选择奇数:
List<int> collection = new List<int> { 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)
通过命令式编程,我们将逐步完成,并决定我们想要什么:
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们说:
另一方面,使用声明性编程,您可以编写描述所需内容的代码,但不一定是如何获取代码(声明您想要的结果,而不是逐步说明):
var results = collection.Where( num => num % 2 != 0);
Run Code Online (Sandbox Code Playgroud)
在这里,我们说"给我们所有奇怪的东西",而不是"逐步收集.检查这个项目,如果它很奇怪,将它添加到结果集合中."
在许多情况下,代码也将是两种设计的混合,因此它并不总是黑白的.
Mar*_*off 136
声明式编程是当你说什么,你想要的,命令式语言是当你说怎么得到你想要的东西.
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)
Run Code Online (Sandbox Code Playgroud)
第一个示例是声明性的,因为我们没有指定构建列表的任何"实现细节".
为了结合C#示例,通常使用LINQ会产生声明式样式,因为您没有说明如何获得所需内容; 你只说什么你想要的.你可以对SQL说同样的话.
声明性编程的一个好处是它允许编译器做出可能导致代码比手工编写的代码更好的决策.运行SQL示例,如果您有类似的查询
SELECT score FROM games WHERE id < 100;
Run Code Online (Sandbox Code Playgroud)
SQL"编译器"可以"优化"这个查询,因为它知道这id是一个索引字段 - 或者它可能没有索引,在这种情况下,它必须遍历整个数据集.或许SQL引擎知道这是利用所有8个内核进行快速并行搜索的最佳时机. 你,作为一个程序员,不关心任何这些条件,你不必编写代码来处理这样的任何特殊情况.
Ali*_*imi 95
声明与命令
一个编程范式是计算机编程的基本风格.有四种主要范例:命令式,声明式,功能性(被认为是声明性范式的一个子集)和面向对象.
声明性编程:是一种编程范式,表示计算的逻辑(做什么)而不描述其控制流(如何做).一些着名的声明性域特定语言(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);
Run Code Online (Sandbox Code Playgroud)
两个例子都产生相同的结果,一个既不好也不差.第一个示例需要更多代码,但代码是可测试的,并且命令式方法使您可以完全控制实现细节.在第二个例子中,代码可以说更具可读性; 但是,LINQ并不能让您控制幕后发生的事情.您必须相信LINQ将提供所请求的结果.
eng*_*rce 43
以上所有答案和其他在线帖子提到以下内容:
他们没有告诉我们的是如何实现它.对于更具说明性的程序的一部分,其他部分必须提供抽象来隐藏实现细节(这是必要的代码).
实际上,函数式编程和函数库更具声明性的原因之一是因为它们抽象了循环和列表创建,隐藏了场景背后的所有实现细节(最有可能是带循环的命令式代码).
在任何程序中,您将始终拥有命令性和声明性代码,您应该的目标是隐藏抽象背后的所有命令代码,以便程序的其他部分可以以声明方式使用它们.
最后,尽管函数式编程和LINQ可以使您的程序更具说明性,但您可以通过提供更多抽象来使其更具声明性.例如:
// 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();
Run Code Online (Sandbox Code Playgroud)
Eri*_*bal 42
我将添加另一个很少出现在声明/命令式编程讨论中的例子:用户界面!
在C#中,您可以使用各种技术构建UI.
在命令性结束时,您可以使用DirectX或OpenGL非常强制性地逐行绘制按钮,复选框等...(或者实际上,三角形三角形).您可以自行决定如何绘制用户界面.
在声明性结束时,你有WPF.你基本上写了一些XML(是的,是的,技术上是"XAML"),框架为你工作.你说用户界面是什么样的.由系统决定如何做到这一点.
无论如何,还有另外一件事要考虑.仅仅因为一种语言是声明性的或命令式的,并不意味着它没有另一种语言的某些特征.
此外,声明性编程的一个好处是,通过阅读代码通常可以更容易地理解目的,而命令式可以让您更好地控制执行.
这一切的要点:
声明 - > what你想要完成
势在必行 - > how你想要它完成
ROM*_*eer 24
我喜欢剑桥课程的解释+他们的例子:
int x; - 什么(声明)x=x+1; - 怎么样Gor*_*ulu 23
命令式编程要求开发人员逐步定义代码的执行方式.要以强制性的方式发出指示,你会说:"去第一街,左转进入Main,开两个街区,右转进入Maple,然后停在左边的第三个房子."声明版可能听起来像这样:"开车去苏的家."一个人说怎么做; 另一个人说需要做什么.
声明式风格比命令式风格有两个优点:
- 它不会强迫旅行者记住一长串指令.
- 它允许旅行者在可能的情况下优化路线.
Calvert,C Kulkarni,D(2009).必不可少的LINQ.艾迪生韦斯利.48.
Luc*_*Fox 19
差异主要与整体抽象水平有关.使用声明,在某些时候,你离各个步骤太远,程序在如何获得结果方面有很大的自由度.
你可以看到每一条指令都落在连续体的某个地方:
抽象程度:
Declarative <<=====|==================>> Imperative
Run Code Online (Sandbox Code Playgroud)
声明性真实世界示例:
势在必行的现实世界示例:
McK*_*Kay 10
命令式编程明确告诉计算机该做什么,以及如何做,如指定顺序等
C#:
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)
陈述是当你告诉计算机做什么,但不是真的如何做.Datalog/Prolog是这方面首先想到的语言.基本上一切都是陈述性的.你不能真正保证订单.
C#是一种更为迫切的编程语言,但某些C#特性更具说明性,如Linq
dynamic foo = from c in someCollection
let x = someValue * 2
where c.SomeProperty < x
select new {c.SomeProperty, c.OtherProperty};
Run Code Online (Sandbox Code Playgroud)
必须写同样的事情:
dynamic foo = SomeCollection.Where
(
c => c.SomeProperty < (SomeValue * 2)
)
.Select
(
c => new {c.SomeProperty, c.OtherProperty}
)
Run Code Online (Sandbox Code Playgroud)
(来自维基百科Linq的例子)
在计算机科学中,声明性编程是一种编程范式,它在不描述其控制流的情况下表达计算的逻辑.
来自http://en.wikipedia.org/wiki/Declarative_programming
简而言之,声明性语言更简单,因为它缺乏控制流的复杂性(循环,if语句等)
一个很好的比较是ASP.Net'代码隐藏'模型.你有声明的'.ASPX'文件,然后是命令式'ASPX.CS'代码文件.我经常发现,如果我可以在脚本的声明性一半中完成所有我需要的工作,那么更多的人可以按照正在做的事情来完成.
小智 7
从Philip Roberts偷窃:
两个例子:
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]
Run Code Online (Sandbox Code Playgroud)
声明的:
var numbers = [1,2,3,4,5]
var doubled = numbers.map(function(n) {
return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
以声明
var numbers = [1,2,3,4,5]
var total = numbers.reduce(function(sum, n) {
return sum + n
});
console.log(total) //=> 15
Run Code Online (Sandbox Code Playgroud)
注意命令性示例如何涉及创建新变量,改变它并返回该新值(即,如何使某些事情发生),而声明性示例在给定输入上执行并基于初始输入返回新值(即,我们想要发生什么).
| 归档时间: |
|
| 查看次数: |
184795 次 |
| 最近记录: |