js跳出函数_前端函数式演进之:一、语言范式和前端体现

c4d3fe428c9f247b97df7c054fd51e07.png

前端开发的工具更迭和新知识点学习总是伴随着工作。近年来,函数式编程思想已经从各方面影响着我们的工具、规范,尤其是 ES和它周边工具的演进。

从源头上说,JS具备的一些特性,和前端(含Node)程序多入口驱动、事件流较多的特性,对函数式思想也有天然的亲和。

作为在互联网浪潮中蓬勃发展的前端工程师,不总结就很难容纳更多知识。我希望能结合自己的前端经验,尝试从语言范式、 函数式基础概念、 函数式思维、Monad介绍、 函数式工具库演进、 事件流和函数响应式编程几个方面逐步描述函数式的概念、思维、演进和在前端的体现,大家相互印证,多多指正。
你们可以在后面的过程中看到一些概念名词,进而进行扩展查询; 也将看到函数式编程思想的优点、在前端的体现、以及前端工具链中的 map、pipe、flatMap 进而到 Promise、Rxjs 的演进历程。

一 编程范式

编程范式是我们使用的高级语言的一些设计准则。


这些设计准则约定了我们以什么样的方式告诉机器环境(编译器或更底层,以下统称机器或环境)我们希望传达的信息。


实际上的编程范式比较多,主要可以分为两种: 想要告诉机器怎么利用他的穷举、跳转和记忆,逐步地完成我们交付的事情(命令式); 想要告诉机器我们要什么(声明式),由机器按照已在编译器中实现的策略来完成任务。


此外,还有一些和之上方式并不冲突的常见语言设计准则,比如 面向对象、元编程等。

二 命令式编程 Imperative Programming

有其他名字如指令式、过程式 (Procedural programming)。

我们一般理解为 顺序编程 加一些控制流程的语句。


比如运算语句、循环语句(while、for)、条件分支语句(if)、 无条件分支语句(goto、程序调用等)。

程序调用的对象包括,由包含一系列运算步骤的程序(Procedures)、 例程(Routines)、子程序(Subroutines)、方法(methods)、函数(functions),我们在JS里可以统一理解为模块中的方法。

命令式编程是我们学习很多新语言都普遍具备的编程方法,区别多在于:


变量使用前是否需要申明、变量作用域、变量基本类型、集合的类型、等等。

命令式编程在我们的代码中广泛存在,尤其在使用框架之前的早期代码(jQuery时代),以及当前业务框架的各个生命周期方法和业务代码中(init方法,接口调用逻辑中)。

代码示例(代码示例不一定是JS代码,可能有伪代码和其他语言):

sum 

三 面向对象 Object-oriented programming / OOP

把计算机程序视为一组对象的集合。
而每个对象都可以接收并处理其他对象发过来的消息,计算机程序的执行就是一系列消息在各个对象之间的传递。

前端开发听到的面向对象多来自后端的JAVA开发同学。JAVA在很多层面贯彻了面向对象和它的三大要素(继承、封装、多态),而我们看到的代码形式多是class 和一个个的包。因为和Java的密切关系,我们引入了 class和诸多语法糖,虽然我们日常的使用并不一定很贴切它的初衷。

代码示例(Python)

class 

而实际上,前端的很多编码内容都有面向对象的设计思想在,比如我们的组件。
大家可以离开class,思考组件或者说前端的业务模块 是怎样实现 继承(扩展)、封装、多态、消息传递等。

面向对象的编程思想基于高效的信息抽象(将事物或过程抽象成一类信息的个体,继而生成信息岛屿),再寻求建立事物或过程之间的联系。
它是一种很好地处理将现实中已有事物和过程抽象到计算机信息系统中的方法。

四 元编程 Metaprogramming

编写或者操纵其他程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。

代码示例(Ruby)

>> a
NameError: undefined local variable or method `a' for main:Object
from (irb) 1
>> ruby has no bare words
NameError: undefined local variable or method `words' for main:Object
from (irb) 1
>> def method_missing(*args); args.join(" "); end
=> nil
>> ruby has bare words
=> "ruby has bare words"
>> bare words can even have bangs!
=> "bare words can even have bangs!" 

在Ruby中,我们可以通过 method_missing 快速定义语法层面的方法。 上面代码中 "ruby has no bare words" 这个没有关键字的句子,前后两次的输出结果截然不同。

事实上,因为JS的原型继承和解释型语言的特性,我们可以通过对基础类型的原型方法的重新定义实现一些类似的功能;还可以通过装饰器、代理、Babel插件等工具做更多类似的事情。
我们可以在运行时完成更多类似操作的代价,就是也要承担程序运作时的语法错误风险。

元编程,或者运行环境的元信息在我们制作工具,或者想上寻求更多能力时是至关重要的。

关于我们的代码,我们总是在想在开发平台(可视化搭建、二次开发平台)、业务组件代码、构建时代码、运行时代码等多个层级逐级向上做切面开发和元编程,大家可以识别下在每次突破次元壁时需要操作的环境内容。

五 声明式编程 Declarative programming

声明式编程编码时关注做到什么而不是怎么做,我们像老板一样交付要做的事情,而不是亲力亲为关注最优的ROI和效率。

我们常见到的语言和平台有: 正则表达式,逻辑式编程,函数式编程和组态管理系统(配置管理)等。

代码层面的简单例子比如 map 和 for...in循环的使用: 使用对可枚举集合的整体指令代替了while和for的步进操作。

领域专用语言(Domain Specific Language/ DSL)是在设计一个系统的顶层经常出现的语言形式,它不一定有完备的编程语言特征,但一般都能描述清楚编码者需要的信息,多数符合声明式编程特征:


我们可以接触到的有 SQL、XQuery、CSS、Vue/Angular 的Controller(数据在模板文件上的绑定)等。

代码示例

SELECT 

声明式编程的内容实际上很宽泛。我们跳出一些功能代码的内部实现就可以把外部的调用看成声明式的。


那么小到一个语法糖,大到人工智能、逻辑式和函数式编程都可以归纳到其中。

六 逻辑式编程 Logic programming

约束满足问题(Constraint Satisfaction Problem / CSP) 是变量集合和约束条件的集合。问题的领域涉及到NP复杂算法和人工智能级别的一些问题。

Prolog这个语言使用了一个深度优先搜索的决策树 ,它使用所有可能组合与规则集合相匹配 ,且其编译器对这个过程做了很好的优化 。
不过,这个策略需要进行大量计算 , 特别是当数据数据规模非常大的时。

以下通过一个Prolog的实例给大家展示逻辑式编程的一隅

//  

像一道数学题一样,我们给出公理(事实)、已知条件(规则)、问题(查询),编码语言给出输出结果。

结果并不一定是唯一的,但它总是正确的。
像是我们在某些早期浏览器里对对象的查询显示,或是期望得到一个满足条件的随机数。

七 函数式编程 Functional programming

函数式编程是基于 λ演算 lambda calculus的一种编程语言模式,它的理论基础基于 λ演算、α-等价、β-归约。

我们现在知道它和传统命令式语言(C类)基于完全不同的逻辑表现形式、但可以做到一样的事物表达就可以了。
在它的理论基础下还有一些概念我们可以在后面逐渐了解讨论。

函数式编程通常是声明式编程中的内容,因为我们关注输入和输出的结果多过关注实现的过程。
它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。

常见的函数式语言有 Scala Lisp Clojure Haskell OCaml;
在前端 React的出现帮助我们更好地约束副作用、基于function演进生成整个前端系统。前端的范畴下我们还可以关注lodash、Elm、Rxjs等工具和语言,他们和React一样有着函数式思想的一些体现。

代码示例(Lisp)

(

在不借助工具库的情况下,JS和纯粹的函数式编程契合的点主要有First-class function、Lamda表达式、闭包、数组组合子等;但同时缺少了不可变数据结构、惰性求值等内容。

八 小结 关于前端

在比较编程范式时,我们更多的是比较编程范式体现的思想。


相比于我们了解更多的命令式和其他范式思想,函数式的优点在于可以通过减少副作用,提高我们的缓存能力、测试的可行性、事件流的可读性;随着函数式工具的演进,状态管理工具(异步状态管理)、函数响应式编程等内容帮我们更好地梳理业务流程。这些可以充分弥补前端编程走向成熟时的不足。

JS是一个多范式语言,我们同样也需要很好地处理事物的抽象、对环境的掌控等;

前端除了JS,还有浏览器方法、CSS、HTML、Node服务,熟悉语言范式和多了解一些语言或框架的feature能帮助我们理解前端技术的内部原理和进行借鉴。和大家一起学习,希望多多指正。

附: 以上部分示例来自于经典的 《七周七语言》,推荐大家

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值