C# 声明式编程和命令式编程有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1784664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:47:44  来源:igfitidea点击:

What is the difference between declarative and imperative programming?

c#paradigmsimperative-programmingdeclarative-programming

提问by Brad

I have been searching the web looking for a definition for declarative and imperative programming that would shed some light for me. However, the language used at some of the resources that I have found is daunting - for instance at Wikipedia. Does anyone have a real-world example that they could show me that might bring some perspective to this subject (perhaps in C#)?

我一直在网上搜索声明式和命令式编程的定义,这将为我提供一些启发。但是,我发现的一些资源中使用的语言令人生畏 - 例如在Wikipedia 上。有没有人有一个现实世界的例子,他们可以向我展示这可能会给这个主题带来一些视角(也许在 C# 中)?

采纳答案by Reed Copsey

A great C# example of declarative vs. imperative programming is LINQ.

声明式与命令式编程的一个很好的 C# 示例是 LINQ。

With imperativeprogramming, you tell the compiler what you want to happen, step by step.

通过命令式编程,您可以一步一步地告诉编译器您想要发生的事情。

For example, let's start with this collection, and choose the odd numbers:

例如,让我们从这个集合开始,并选择奇数:

List<int> collection = new List<int> { 1, 2, 3, 4, 5 };

With imperative programming, we'd step through this, and decide what we want:

使用命令式编程,我们会逐步完成,并决定我们想要什么:

List<int> results = new List<int>();
foreach(var num in collection)
{
    if (num % 2 != 0)
          results.Add(num);
}

Here, we're saying:

在这里,我们要说的是:

  1. Create a result collection
  2. Step through each number in the collection
  3. Check the number, if it's odd, add it to the results
  1. 创建结果集合
  2. 遍历集合中的每个数字
  3. 检查数字,如果是奇数,则将其添加到结果中

With declarativeprogramming, on the other hand, you write code that describes what you want, but not necessarily how to get it (declare your desired results, but not the step-by-step):

另一方面,使用声明式编程,你编写的代码描述了你想要什么,但不一定是如何得到它(声明你想要的结果,但不是一步一步):

var results = collection.Where( num => num % 2 != 0);

Here, we're saying "Give us everything where it's odd", not "Step through the collection. Check this item, if it's odd, add it to a result collection."

在这里,我们说“给我们所有奇怪的东西”,而不是“遍历集合。检查这个项目,如果它是奇怪的,把它添加到结果集合中。”

In many cases, code will be a mixture of both designs, too, so it's not always black-and-white.

在许多情况下,代码也将是两种设计的混合,所以它并不总是黑白分明的。

回答by Mark Rushakoff

Declarative programming is when you say whatyou want, and imperative language is when you say howto get what you want.

声明式编程是你说你想要什么,命令式语言是你说如何得到你想要的。

A simple example in Python:

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)

The first example is declarative because we do not specify any "implementation details" of building the list.

第一个示例是声明性的,因为我们没有指定构建列表的任何“实现细节”。

To tie in a C# example, generally, using LINQ results in a declarative style, because you aren't saying howto obtain what you want; you are only saying whatyou want. You could say the same about SQL.

结合 C# 示例,通常,使用 LINQ 会产生声明式风格,因为您并没有说明如何获得您想要的;你只说什么你想要的。您可以对 SQL 说同样的话。

One benefit of declarative programming is that it allows the compiler to make decisions that might result in better code than what you might make by hand. Running with the SQL example, if you had a query like

声明式编程的一个好处是它允许编译器做出可能产生比您手工编写的代码更好的代码的决定。使用 SQL 示例运行,如果您有类似的查询

SELECT score FROM games WHERE id < 100;

the SQL "compiler" can "optimize" this query because it knows that idis an indexed field -- or maybe it isn't indexed, in which case it will have to iterate over the entire data set anyway. Or maybe the SQL engine knows that this is the perfect time to utilize all 8 cores for a speedy parallel search. You, as a programmer, aren't concerned with any of those conditions, and you don't have to write your code to handle any special case in that way.

SQL“编译器”可以“优化”这个查询,因为它知道这id是一个索引字段——或者它可能没有索引,在这种情况下它无论如何都必须迭代整个数据集。或者 SQL 引擎可能知道这是利用所有 8 个内核进行快速并行搜索的最佳时机。 ,作为一个程序员,不关心任何这些条件,你不必编写代码来处理这样的任何特殊情况。

回答by kervin

In computer science, declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.

在计算机科学中,声明式编程是一种编程范式,它表达计算的逻辑而不描述其控制流。

From http://en.wikipedia.org/wiki/Declarative_programming

来自http://en.wikipedia.org/wiki/Declarative_programming

in a nutshell the declarative language is simpler because it lacks the complexity of control flow ( loops, if statements, etc. )

简而言之,声明式语言更简单,因为它缺乏控制流(循环、if 语句等)的复杂性。

A good comparison is the ASP.Net 'code-behind' model. You have declarative '.ASPX' files and then the imperative 'ASPX.CS' code files. I often find that if I can do all I need in the declarative half of the script a lot more people can follow what's being done.

一个很好的比较是 ASP.Net 'code-behind' 模型。您有声明性的“.ASPX”文件,然后是命令性的“ASPX.CS”代码文件。我经常发现,如果我能在脚本的声明性部分完成我需要的所有事情,那么更多的人可以了解正在做的事情。

回答by McKay

Imperative programming is telling the computer explicitly what to do, and how to do it, like specifying order and such

命令式编程是明确地告诉计算机要做什么以及如何做,例如指定顺序等

C#:

C#:

for (int i = 0; i < 10; i++)
{
    System.Console.WriteLine("Hello World!");
}

Declarative is when you tell the computer what to do, but not really how to do it. Datalog / Prolog is the first language that comes to mind in this regard. Basically everything is declarative. You can't really guarantee order.

声明性是当您告诉计算机要做什么,而不是真正如何做时。Datalog / Prolog 是这方面想到的第一种语言。基本上一切都是声明性的。你不能真正保证订单。

C# is a much more imperative programming language, but certain C# features are more declarative, like Linq

C# 是一种更加命令式的编程语言,但某些 C# 功能更具声明性,例如 Linq

dynamic foo = from c in someCollection
           let x = someValue * 2
           where c.SomeProperty < x
           select new {c.SomeProperty, c.OtherProperty};

The same thing could be written imperatively:

同样的事情可以命令式地写:

dynamic foo = SomeCollection.Where
     (
          c => c.SomeProperty < (SomeValue * 2)
     )
     .Select
     (
          c => new {c.SomeProperty, c.OtherProperty}
     )

(example from wikipedia Linq)

(来自维基百科 Linq 的例子)

回答by Erich Mirabal

I'll add another example that rarely pops up in declarative/imperative programming discussion: the User Interface!

我将添加另一个在声明式/命令式编程讨论中很少出现的示例:用户界面!

In C#, you can build an UI using various technologies.

在 C# 中,您可以使用各种技术构建 UI。

On the imperative end, you could use DirectX or OpenGL to very imperatively draw your buttons, checkboxes, etc... line-by-line (or really, triangle by triangle). It is up to you to say how to draw the user interface.

在命令式的一端,您可以使用 DirectX 或 OpenGL 来非常命令式地绘制按钮、复选框等……一行一行(或者实际上,一个三角形一个三角形)。由您决定如何绘制用户界面。

At the declarative end, you have WPF. You basically write some XML (yeah, yeah, "XAML" technically) and the framework does the work for you. You say what the user interface looks like. It is up to the system to figure out how to do it.

在声明性的最后,你有 WPF。您基本上编写了一些 XML(是的,是的,技术上是“XAML”),框架会为您完成工作。你说用户界面是什么样的。由系统来决定如何去做。

Anyway, just another thing to think about. Just because one language is declarative or imperative does not mean that it doesn't have certain features of the other.

无论如何,只是要考虑的另一件事。仅仅因为一种语言是声明性或命令性的,并不意味着它没有另一种语言的某些特征。

Also, one benefit of declarative programming is that purpose is usually more easily understood from reading the code whereas imperative gives you finer control over execution.

此外,声明式编程的一个好处是通过阅读代码通常更容易理解目的,而命令式可以让您更好地控制执行。

The gist of it all:

这一切的要点:

Declarative -> whatyou want done

声明式 ->what你想完成

Imperative -> howyou want it done

当务之急 ->how你想要它完成

回答by AliKarimi

Declarative vs. Imperative

声明式与命令式

A programming paradigmis a fundamental style of computer programming. There are four main paradigms: imperative, declarative, functional (which is considered a subset of the declarative paradigm) and object-oriented.

一个编程范式是计算机编程的基本风格。有四种主要范式:命令式、声明式、函数式(被认为是声明式范式的子集)和面向对象。

Declarative programming: is a programming paradigm that expresses the logic of a computation(What do) without describing its control flow(How do). Some well-known examples of declarative domain specific languages (DSLs) include CSS, regular expressions, and a subset of SQL (SELECT queries, for example) Many markup languages such as HTML, MXML, XAML, XSLT... are often declarative. The declarative programming try to blur the distinction between a program as a set of instructions and a program as an assertion about the desired answer.

声明式编程:是一种编程范式,它表达计算的逻辑(做什么)而不描述其控制流(如何做)。声明性域特定语言 (DSL) 的一些著名示例包括 CSS、正则表达式和 SQL 的子集(例如,SELECT 查询) 许多标记语言,例如 HTML、MXML、XAML、XSLT……通常是声明性的。声明式编程试图模糊作为一组指令的程序和作为关于所需答案的断言的程序之间的区别。

Imperative programming: is a programming paradigm that describes computation in terms of statements that change a program state. The declarative programs can be dually viewed as programming commands or mathematical assertions.

命令式编程:是一种编程范式,它根据改变程序状态的语句来描述计算。声明性程序可以被双重视为编程命令或数学断言。

Functional programming : is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. In a pure functional language, such as Haskell, all functions are without side effects, and state changes are only represented as functions that transform the state.

函数式编程:是一种将计算视为数学函数的评估并避免状态和可变数据的编程范式。它强调函数的应用,而命令式编程风格则强调状态的变化。在像 Haskell 这样的纯函数式语言中,所有的函数都是没有副作用的,状态变化只表示为转换状态的函数。

The following example of imperative programming in MSDN, loops through the numbers 1 through 10, and finds the even numbers.

以下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);

Both examples yield the same result, and one is neither better nor worse than the other. The first example requires more code, but the code is testable, and the imperative approach gives you full control over the implementation details. In the second example, the code is arguably more readable; however, LINQ does not give you control over what happens behind the scenes. You must trust that LINQ will provide the requested result.

两个例子产生相同的结果,一个既不比另一个好也不差。第一个示例需要更多代码,但代码是可测试的,命令式方法使您可以完全控制实现细节。在第二个示例中,代码可以说更具可读性;但是,LINQ 并不能让您控制幕后发生的事情。您必须相信 LINQ 会提供请求的结果。

回答by Puneet Sharma

Just to add another example in terms of mobile app development. In iOS and Android, we have Interface Builders, where we can define UI of the apps.

只是在移动应用程序开发方面添加另一个示例。在 iOS 和 Android 中,我们有界面构建器,我们可以在其中定义应用程序的 UI。

The UI drawn using these Builders is declarative in nature, where we drag and drop the components. The actual drawing happens underneath and performed by the framework and system.

使用这些构建器绘制的 UI 本质上是声明性的,我们可以在其中拖放组件。实际绘图发生在框架和系统之下并由框架和系统执行。

But we can also draw the whole components in code, and that is imperative in nature.

但是我们也可以在代码中绘制整个组件,这在本质上是命令式的。

Also, some new languages like Angular JS are focussing on designing UIs declaratively and we may see a lot of other languages offering the same support. Like Java doesn't have any good declarative way to draw native desktop apps in Java swing or Java FX but in the near future, they just might.

此外,一些新语言(如 Angular JS)专注于以声明方式设计 UI,我们可能会看到许多其他语言提供相同的支持。就像 Java 没有任何好的声明方式在 Java swing 或 Java FX 中绘制本机桌面应用程序一样,但在不久的将来,它们可能会。

回答by GorkemHalulu

Imperative programming requires developers to define step by step how code should be executed. To give directions in an imperative fashion, you say, “Go to 1st Street, turn left onto Main, drive two blocks, turn right onto Maple, and stop at the third house on the left.” The declarative version might sound something like this: “Drive to Sue's house.” One says how to do something; the other says what needs to be done.

The declarative style has two advantages over the imperative style:

  • It does not force the traveler to memorize a long set of instructions.
  • It allows the traveler to optimize the route when possible.

命令式编程要求开发人员逐步定义应如何执行代码。要以命令式方式指示方向,您可以说:“去 1st Street,左转进入 Main,行驶两个街区,右转进入 Maple,然后在左边的第三个房子停下。” 声明性版本可能听起来像这样:“开车去苏家。” 一个说如何做某事;另一个说需要做什么。

声明式风格与命令式风格相比有两个优点:

  • 它不会强迫旅行者记住一长串说明。
  • 它允许旅行者在可能的情况下优化路线。

Calvert,C Kulkarni,D (2009). Essential LINQ. Addison Wesley. 48.

Calvert,C Kulkarni,D (2009)。基本的 LINQ。艾迪生·韦斯利。48.

回答by Chris Eaves-Kohlbrenner

Stealing from Philip Roberts here:

在这里菲利普罗伯茨那里偷窃:

  • Imperative programming tells the machine how to do something (resulting in what you want to happen)
  • Declarative programming tells the machine what you would like to happen (and the computer figures out how to do it)
  • 命令式编程告诉机器如何做某事(导致你想要发生的事情)
  • 声明式编程告诉机器你想发生什么(计算机会弄清楚如何去做)

Two examples:

两个例子:

1. Doubling all numbers in an array

1. 将数组中的所有数字加倍

Imperatively:

当务之急:

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]

Declaratively:

声明:

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. Summing all items in a list

2. 汇总列表中的所有项目

Imperatively

当务之急

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

Declaratively

声明式地

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Note how the imperative examples involve creating a new variable, mutating it, and returning that new value (i.e., how to make something happen), whereas the declarative examples execute on a given input and return the new value based on the initial input (i.e., what we want to happen).

请注意命令式示例如何涉及创建一个新变量、对其进行变异并返回该新值(即,如何使某事发生),而声明式示例在给定输入上执行并根据初始输入返回新值(即,我们想要发生的事情)。

回答by ROMANIA_engineer

I liked an explanation from a Cambridge course + their examples:

我喜欢剑桥课程的解释+他们的例子:

  • Declarative- specify whatto do, not howto do it
    • E.g.: HTML describes what should appear on a web page, not how it should be drawn on the screen
  • Imperative- specify both whatand how
    • int x;- what (declarative)
    • x=x+1;- how
  • 声明性- 指定要做什么而不是如何
    • 例如:HTML 描述应该出现在网页上的内容,而不是它应该如何在屏幕上绘制
  • 势在必行- 指定内容方式
    • int x;- 什么(声明性的)
    • x=x+1;- 如何