转载如下:

reference:

http://tutorials.jenkov.com/the-declarative-delusion.html

I often read or hear developers saying that declarative programming languages are better than imperative programming languages. I believe that to be a mistake. In my opinion declarative programming languages are never better than imperative programming languages. Don't get me wrong. There are definitely cases for which a declarative approach is more appropriate than an imperative approach, but it is far from every case, and a declarative approach does not necessarily mean you have to use a declarative language. In this text I will explain why.

Declarative vs Imperative Programming Languages

Before I get into an argument about declarative and imperative programming languages, let me just take a moment to explain what they are.

declarative programming language is a language which enables you to express what you want done, and not explicitly how you want it done. Examples of declarative languages are HTML, XML, CSS, JSON and SQL, and there are more.

An imperative programming language is a language that express how you want something done, as a series of smaller steps of a whole. Examples of imperative languages are C, C++, C#, Java, JavaScript, Scala, Ruby, Python, and there are way more out there.

Declarative programming languages are typically designed to address a very specific problem.

Imperative languages typically are designed to let you address any kind of problem.

The Declarative Delusion Defined

Declarative programming languages are not crap by default. The delusion happens when developers start believing that declarative languages are better than imperative languages. This belief is what I call the declarative delusion.

The declarative delusion makes developers believe that just specifying what is much better than specifying how. The delusion probably stems from the fact that it is often (but not always) shorter to specify what, than how.

Developers suffering from the declarative delusion will always gravitate towards a declarative language or approach, even in situations where an imperative approach or language would be much better.

A Developer's Job is Imperative

Before I even explain why declarative languages are far from always better than imperative, let me first examine the whole infatuation with what over how.

As a developer, your whole job consist of finding out how to do things. Your customers, managers, founders etc. are the ones who specify what and you need to find a way to get it done. If you are a founding developer, you get to say what to do, but you are still left with the job of finding out how to do it too.

I can understand why just having to specify what feels good. It's short, and the how becomes somebody elses problem. It's like giving orders. Humans often like giving orders (unfortunately).

Luckily, we developers get to give orders too from time to time. When we delegate work to other developers or subcontractors, and when we call APIs, or use declarative languages or approaches. But - developer's job is inherently imperative even if parts can be handled declaratively. Therefore it doesn't make sense as a developer to favor the what over the how. The how is our job. It's what we do.

Declarative Programs are Executed by Imperative Program

A computer cannot execute what. A computer need to know explicitly how to do it, step for step. It can only execute how. Therefore a declarative program is always an input to an imperative program which figures out how to execute the what. Declarative and imperative go hand in hand.

The Declarative Strengths

Declarative languages are often designed to address a very specific problem or use case (domain). In other words, declarative languages are often domain specific languages (DSL).

Being domain specific, targeted at a very specific problem domain, declarative languages are often very concise. The language doesn't need features for every possible problem on the planet. Just enough to solve problems within its domain.

Second, declarative languages may sometimes be easier to learn for non-programmers. Since declarative languages are domain specific, the language often looks closer to the verbal language used within that domain. For instance, SQL has been learned by lots of non-programmers. If you are a data analyst and you understand data, relational databases, and know what questions you want to answer with that data, SQL will feel more natural to you than e.g. JavaScript.

Third, since declarative languages may be easier to learn for non-programmers, declarative DSLs can be a way to empower non-programmers in an organisation. A DSL may enable non-programmers to have a more advanced interaction with a system. For instance, data analysts can create their own reports rather than having to get a developer to do it.

The Declarative Weaknesses

The fact that declarative languages are often easier to use, often become their weakness too. Often you start out writing simple logic in your declarative language, but as your abilities and requirements grow, your programs become more and more demanding. And sooner or later you hit the declarative wall: You find yourself in a situation where you need to specify how something is to be done. The what is no longer enough.

The reason you often hit the declarative wall is exactly that these languages are often designed to solve a very specific problem. The language designer did not think of everything, and you hit the wall when you need something the language designer did not think of. In fact, if the language should enable you do solve every problem under the sun, it would end up being pretty close to an imperative language.

When enough users of a declarative programming language hits its declarative wall, the result is usually that the declarative language is extended with features that support the needed use cases. Sometimes this can be done elegantly. Often, however, the concise syntax of the given declarative language starts to break down. The language starts becoming more complex than an implementation in an imperative language would have been.

SQL windowing functions is a great example. Imagine you need to iterate over a result set and calculate the difference between values of different rows. This was not possible in SQL until windowing functions were added (2003). The SQL windowing function syntax is not pretty. Such operations could most likely have been expressed almost as concisely, and probably be more readable using many popular imperative languages.

There are still many operations on data that you cannot easily do with SQL. For instance, to my knowledge you cannot combine reads and writes into a single, atomic operation. This is beyond SQL's declarative wall. To solve these kinds of problems, many databases support stored procedures. Stored procedure languages are often imperative, but can call the declarative SQL from inside the language.

If we had just started with an imperative query language (IQL) from the beginning, it would have been possible to express data manipulations more freely from the beginning. Imperative languages evolve too, to make them easier and more conciset to use, but at least you could do pretty much anything even with the first versions of most popular, imperative languages. It might have been more verbose, but at least you didn't hit a wall.

Additionally, with an IQL, stored procedures would be a natural part of the language instead of something each database vendor implements on their own, in different versions.

Shameless plug: At vstack.co we are exactly creating a database that uses an imperative query language instead of SQL.

You see the same phenomenon with CSS. Expressing CSS styling for bigger web applications have become so verbose that developers have started using CSS pre-processors like LESS and Sass. Why? Because developers felt they need features like inheritance, variables, calculations etc. Yes, these features are still reasonably easy to express declaratively, so they could perhaps be added to CSS. But sooner or later the CSS syntax may break down too. I, for one, will be experimenting with using JavaScript to define CSS styles in the future. Just to make sure I have the imperative features if I should need them.

Most Imperative Languages are Also Declarative

Many popular programming languages are classified as imperative even though they are also partly declarative. This includes the popular languages C, C++, C#, Java, JavaScript, Scala, Ruby and Python. I will explain what I mean below.

The following JavaScript code calculates the interest of capital over 5 periods (typically years):

var capital  = 100;
var interest = 0.10; //10% per period
var periods  = 5;var result = capital;
for(var i = 0; i < periods; i++) {result = result * (1 + interest);
}

This code is clearly imperative. The calculation is performed using a series of steps. After the code has been executed the result variable will contain the result of the calculation.

Would it not be easier if the above calculation could just have been expresses declaratively? Something like

result = capital with interest : 100 0.1 5

With a very simple "trick", it actually can. Well not exactly like above, but close enough. Look at this JavaScript code:

function capitalWithInterest(capital, interest, periods) {var result = capital;for(var i = 0; i < periods; i++) {result = result * (1 + interest);}return result;
}

Yes, that is right! A simple function definition! Now I can express the result of an interest calculation declaratively like this:

var result = capitalWithInterest(100, 0.1, 5);

JavaScript function definitions are imperative, but function calls declarative. Functions separate the whatfrom the how. When you call a function you usually don't care how it is implemented. You just want the job done. That is declarative.

Fantastic, isn't it? And even better - pretty much any modern programming language support functions. At least the ones I mentioned earlier.

In fact, pretty much any kind of abstraction mechanism we use in our modern languages serve a similar purpose. Abstractions separate the what from the how. They separate interface (what) fromimplementation (how). This is true for functions / methods, interfaces, classes and objects, and for bigger APIs as well (e.g. Java IO, JDBC, your own APIs etc).

JavaScript also contains a declarative way to express state. Look at this:

var myObj = { field1 : "val1", field2 : "val2" };

This example uses the JSON notation to configure an object with fields. JSON is declarative, but you can use JSON from inside JavaScript.

The imperative way of configuring the object above would have been the following stepwise actions:

var myObj = {};myObj.field1 = "val1";
myObj.field2 = "val2";

Some programming languages also enable you to express XML declaratively, similarly to how objects are expressed in JSON.

State vs. Actions

Declarative languages tend to be very good at expressing state (data). For instance, HTML expresses a document structure, CSS expresses styling properties on the document structure (styling is state), and JSON expresses object structures. They all do what they do reasonably well, as long as what you are trying to do is pretty straightforward (good - not perfect).

Because declarative languages are good at expressing state it is often tempting to use a declarative language or approach when generating state. For instance, to use some kind of HTML variant when you are generating HTML from data in a database. JSP (JavaServer Pages), ASP and also AngularJS is based on this idea.

However, generating state based on data (generating data based on other data) is an inherently imperative process. It may be easy to express simple data generation with a declarative approach (e.g. JSP standard tag libraries or AngularJS directives), but as soon as your data generation becomes more complex (and sooner or later it always does), the declarative approach typically breaks down.

Declarative languages are great at expressing state, but imperative languages are better at expressingactions.

Summary

Declarative programming languages are different from imperative languages, but they are not better. If you hear developers say so, they are suffering from the declarative delusion. Point them to this article to cure them.

Declarative languages are usually designed for a specific domain. As long as the domain logic is simple, declarative languages can be very concise and easier to learn for non-programmers. As the domain logic gets more complex, however, an imperative language is typically more appropriate.

Most popular programming languages which are categorized as imperative, also contain declarative elements. Used properly, many such imperative languages can actually mimic declarative languages pretty well, while at the same time provide much more freedom to divert from the original intentions of the declarative language.

Yes, there are many cases where a declarative approach is simpler than an imperative approach, but you can often mimic a declarative approach with most imperative languages. Some languages, like Scala, are even designed to be able to let you define DSLs easily which is translated into simple objects and function calls.

声明式编程比命令式编程更好吗? NO! 你可能陷入了声明式编程的迷幻中!相关推荐

  1. 编程语言的主要类型,声明式编程,命令式编程()和函数式编程的区别

    编程语言的主要类型 Common programming paradigms include imperative which allows side effects, functional whic ...

  2. Imperative vs Declarative声明式编程和命令式编程的比较

    先统一一下概念,我们有两种编程方式:命令式和声明式. 我们可以像下面这样定义它们之间的不同: 命令式编程:命令"机器"如何去做事情(how),这样不管你想要的是什么(what),它 ...

  3. 声明式和命令式编程_命令式与声明式编程

    声明式和命令式编程 At this point you've undoubtedly heard about imperative programming vs declarative program ...

  4. react组件卸载调用的方法_React调用子组件方法与命令式编程误区

    本文将阐述以下内容: 调用DOM元素方法 调用React子组件方法的两种直接方案 自省组件结构设计是否合理 -- 探讨声明式编程与命令式编程在React开发中的问题 调用React子组件方法的最佳方案 ...

  5. 放心!没人在意你使用的是命令式编程还是声明式编程

    作者 | Sunil Sandhu 译者 | 弯月,责编 | 屠敏 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDNnews) 以下为译文: 最初我想写一篇文章详细介绍命令式编 ...

  6. 高阶函数||编程范式: 命令式编程/声明式编程 || 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)

    编程范式: 命令式编程/声明式编程 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数) 高阶函数 filter/map/reduce filter中的回调函数有一个要求: 必须返 ...

  7. 命令式编程面向算法vs声明式编程面向描述

    面向(控制)执行 vs 面向描述 命令式编程面向算法vs声明式编程面向描述. 命令式编程面向:数据结构与算法: 算法 = 控制 + 逻辑: 命令式编程是行动导向(Action-Oriented)的,因 ...

  8. 功能性,声明式和命令式编程[关闭]

    功能,声明和命令式编程这两个术语是什么意思? #1楼 命令式 - 表达式描述要执行的动作序列(关联) 声明性 - 表达式是有助于程序行为的声明(关联,交换,幂等,单调) 功能 -词汇具有值作为唯一的影 ...

  9. 声明式编程与函数式编程_实用程序类与函数式编程无关

    声明式编程与函数式编程 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式 . 绝对是错的! 好吧,我确实认为它们是一个糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先, ...

最新文章

  1. window linux上传文件命令,windows通过cmd命令行使用sftp上传文件至linux
  2. JavaScript面向对象——多继承的实现与理解
  3. 2018 UESTC Training for Data Structures
  4. 【luogu P2764 最小路径覆盖问题】 模板
  5. Alpha版本发布说明
  6. blob 在线解码_roon、NAS图文全攻略 | 试听欧博旗舰RDS1电池数字界面转盘+旗舰RDB1电池解码器(三)。...
  7. 股票历史数据-股票历史数据查询
  8. python身份证验证程序_python 身份证验证
  9. idea常用图标总结
  10. Mysql表数据如何增加汇总统计行(GROUP BY WITH ROLLUP函数用法)
  11. 中兴B860AV2.1-T刷机教程加固件
  12. bochs运行xp_bochs xp镜像完整版
  13. HR必看的86本书籍
  14. c语言写莫迪康通信,常用PLC通信协议有哪些?
  15. 浏览器播放RTSP视频流几种解决方案
  16. iOS 自动续期订阅,订阅升级降级、订阅时间、退收费处理
  17. 无用功[By tina]
  18. Zhong__Centos安装Redis
  19. 零基础如何学习Web安全渗透测试?推荐这份史上最详细的自学路线图!
  20. vue input输入框事件

热门文章

  1. openmpi雅可比迭代法_用雅可比迭代法求线性方程组的解的并行算法(MPI)
  2. mysql wm concat_wm_concat 多行字符串拼接(示例代码)
  3. matlab彩色碎片拼接与复原_碎纸片的拼接复原算法及MATLAB实现.doc
  4. 计算机主机开机滴滴叫,电脑滴滴滴的响而且开不了机怎么办|电脑开机滴滴滴响的解决方法...
  5. 基于微服务架构的餐饮系统的设计与实现计算机毕业设计源码86393
  6. cmd 命令查询域名的 dns 解析记录(A,NS,MX,CNAME,TXT)
  7. 机器学习 - 主成分分析法 (PCA)
  8. Java中的字符集编码入门Java中的增补字符
  9. STM32串口发送16进制数据
  10. viewpage显示服务器图片,照片查看器——ViewPager实现的图片展示控件