zoukankan      html  css  js  c++  java
  • 命令式编程 vs 声明式编程

    实际上我们绝大多数程序员都是在用命令式风格在编程, 这是和我们的冯诺依曼计算机机构密切相关的。 

    (码农翻身注: 参见文章《冯诺依曼计算机的诞生》)

    在一个冯诺依曼计算机中, 最核心的就是CPU和内存, 指令和数据都放在内存当中, CPU每次取出一条指令, 译码,执行,然后把结果写回内存 , 本质就这么简单。

    这些指令是需要程序员精确的告诉计算机的, 当然CPU能理解的都是二进制的机器语言,   只有牛人才能用机器语言和汇编写大型程序,  普通人只能用高级语言来编程 ,例如C, C++, Java , Python等 ,但是高级语言还是要被编译成二进制的机器语言或者用虚拟机/解释器来执行。

    但是即使我们观察下所谓的“高级语言”, 背后依然是冯诺依曼机器的影子:

    那面向对象呢?   其实面向对象本质上也和上表差不多, 运行时也是顺序、条件、循环加上函数调用而已 , 只是在语言层面看来似乎有了封装、继承、多态。

    命令式编程就是对硬件操作的抽象, 程序员需要通过指令,精确的告诉计算机干什么事情。

    这就是程序员苦逼的地方: 需要把复杂的, 容易产生歧义的人类语言翻译成精确的计算机语言指令。

    3

    声明性编程

    最知名的就是SQL了:

    SQL 最大的特点就是只声明我想要什么(What) ,   就是不说怎么做(How)。

    这个怎么做的部分是由数据库管理系统来完成的,  具体的细节自然需要用命令式的编程风格来干活了: 把STUDENT表和STUDENT_SCORE表进行关联, 从磁盘上读取数据,  找出那些分数是80以上的记录, 取出id, name, score 返回。

    再用Java举个例子, 例如有一个学生列表, 我们要计算出年龄小于18的学生数量, 如果用传统的命令式, 代码是这样:

    代码很容易懂:    对students 这个集合, 给我一个一个的遍历啊, 如果学生的年龄小于18 , 把一个计数器加上1  , 对了计数器一定要记着初始化为0啊。

    在Java 8 中, 它对应的声明式则是这样:

    这段代码只是说我要过滤(filter) 一下你这个students 构成的流(stream) , 只把那些年龄小于18的留下, 计算出个数就行了。

    同样的功能,  声明式的代码是不是看起来清爽的多?

    声明性是函数式编程的一个重要特点, 函数式还有其他特点, 像高阶函数、函数没有side effect,  只有值而没有变量, 用递归而不是用迭代等等。  想要完全的掌握函数式需要你彻底的刷新思维, 甚至忘掉命令式的习惯, 所以学习曲线比较陡峭。

    但是这并不妨碍“声明性”这个特点在某些特定领域的应用, 因为它的确能极大的简化代码, 除了上面提到的SQL和Java8 的例子, 在很多领域特定语言里边, 我们的目标就是试图把一个问题尽可能的抽象, 创造一个简单的“小语言”以声明性的方式来描述问题,  不但能简化程序员的工作, 甚至一些业务人员都可以使用了。

    (完)

    你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章

    https://chuansongme.com/n/1158730451444

  • 相关阅读:
    比赛排名机制
    Python 异常(Exception)
    Python 异常(Exception)
    Sobel算子及C++实现
    一题多解(一) —— list(Python)判空(以及 is 与 == 的区别)
    常用软件的常用快捷键
    常用软件的常用快捷键
    从队列、二叉树到优先队列
    Jenkins(二)
    AssertValid函数学习
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10179137.html
Copyright © 2011-2022 走看看