声明式编程的没落
从这几年的发展来看,声明式编程已经日趋式微了。
声明式编程是一种区分于命令式编程的程序语言设计思路。最常见的就是 HTML 和 XML 了,此外还可以把 prolog 等等算上。让我们看看它们的处境。
- UI 领域
HTML 目前已经被 react vue 等 V-DOM 入侵。react 更典型。 react 在输出 UI 时使用 JSX, JSX 具有声明式编程的外观,但它本质上是命令式语言中 object literal 的变形。
WPF 使用声明式编程,这样做可以与编程语言脱钩,你可以使用 VB 和 C# 编写界面后的逻辑,UI归UI逻辑归逻辑。由于 XAML 不能表达业务逻辑,一个 iterator|filter 就属于 advanced technology 了,WPF 开发很吃力。WPF 今天已经越来越没希望,毫无疑问只会更加没落。
Android 还在使用 XML 描述 UI,苹果已经推出和 react 类似的 SwiftUI。
UI 领域的变更,主要原因随着编程交互增多后,网页工程师日趋式微,原来希望的由设计师通过所见即所得工具出 UI 的理想已经破灭,最终 UI 只能由前端程序员完成。
而前端程序员需要软件工程,需要调试。调试是软件工程区别于传统工程的重大差异,调试器可以观察、干预,可以即兴试验,注入输出,这在机械土木等工程中是难以企及的,即使有一些相近的措施也不可能像软件领域这样随时都开发随时都在调试。而声明式语言无法利用调试工具,必须看文档做实验+记忆才能解决的声明式语言的各种歧义。
这样,软件工程的需要导致一直是声明式编程的领域被乔装为声明式的命令式程序占据了。
但是人们对所见即所得的渴望还是存在的,也许有一天它会以类似 gradle 的方式出现,也许是一种更高级的 IDE,可以想象,这是一种 UI 与代码混排的 IDE,UI 在代码中,我能看到它也能实现,可是没有时间。
- Build
从 Java 看,这个领域从从前的 ant, maven 到现在的 gradle,事情已经越来越明显。
ant 是完全的 XML,可以通过一些手段运行 exe 或 Java 类,但它对 build 并不友好,也不负责 dependency。
maven 也是完全的 XML,它解决了 dependency 问题,但纯粹的 XML 使它的 build 功能很糟糕。
gradle 选择了一门看起来很像声明式的语言命令式语言 groovy,不但解决了 dependency 也解决了 build。它还支持调试,可以进行软件工程。一旦 build 发生异常,它会告诉你异常堆栈,能进入断点观察上下文,修改直到成功。
目前各种云厂商的服务器技术正是快速变更的阶段,像 gradle 这样能快速应对变化的技术必然是支持完整软件工程的 build 技术自然脱颖而出。
- 配置
只有配置目前还稳定的属于声明式编程的领域,这方面的佼佼者是 YML。包括容器编排都属于配置范畴。
但一旦配置需要灵活起来,这些配置文件早晚也会被取代。例如有公司在 nginx 接入 lua 脚本,提升网络效率。nginx 配置语言很棒,但它毕竟是声明式语言,如果 nginx 本身是一个脚本,譬如 js 或 groovy,这个技术就更符合软件工程需求了。
有趣的是,从 js python 的 Object literal 发展出来的 JSON,现在已经成为一个常见的配置语言。
- 接口规范
谁能想到现在 gRPC,thrift 等等竟然还在搞 spec generate skeleton 的那一套声明式 DSL,它们早晚会直接打入声明式编程语言中。
- 通用编程
prolog 早就死了,以后也不可能复活了。
- XML 的其它应用场景
VML。VML 只需要表示数据,应用也不广,也没有交互,除非哪天扑向矢量化,到那时 VML 至少会先 react 化。
这里可以讨论一下 3D 技术。3D技术较为滞后,既没有标记语言,也没有出现相应的命令式编程相关技术。传统的 3D 需要映射到 2D 再映射回去,直接针对 3D 的交互不多,现在已经映射到 VR/MR 这种真 3D 空间了,按理说应该出现了。
MyBatis。 MyBatis 将 SQL 嵌在 XML 里,远不如 d2js,d2js 可以使用软件工程技术,和 d2js 相比 MyBatis 就像是一个怪胎。只能说酒香也怕巷子深吧。
声明式编程不符合软件工程要求,无法接入软件工程所需要调试、异常堆栈等技术,有了这些软件工程才能快速迭代,声明式编程终将淘汰,最终被吸纳为一种命令式编程中的风格。