百度已收录

在以前的文章《语言选型通史:快速整合产生的断层》中,我们一直讨论one for all编程语言,开发是一个四栈(语言系统,平台,人,问题/应用)的综合过程,因此对语言的讨论涉及到这四者的边界,只能综合而论。本文档集也一直在探索一种自然不断层方式的native/web,本地/分布APP统一的语言系统和编程模型(其它三栈我们统一称为为appstack/appmodel编程模型,因为它是被开发的主要对象,和语言要处理的目标体)。业界从来都是“先用起来再融合”原则,这使得新旧语言和编程appstack层出不穷。支流分分合合,语言系统在融合appmodel也在融合。事实上,我们开发本来就需要多门语言综合,但业界显然也在探求语言融合之道,先来说语言的融合,它主要分为二部分:

语言技法的融合:语言内的DSL化方向融合
(1)首先是统一前端语言,这是主要的融合方向,我们知道,代表一种语言本身最具辨识度的就是它的写法,也就是技法。新语言都是技法融合的代表,兼容(源码或者api/abi二进制发布级)和多范依然是语言内融合的主要手段,如cpp融合c,go融合lua,rust融合c/cpp,只是,在处理工业需求和学习曲线上,CPP的多范型固然没错,就是复杂化的痕迹很明显。所以会有go这样的语言来简化。这样的结果是出现了多种语言前端和后端组成的语言生态系统(注意这四字,语言从来处在其它三栈的边界,所以是一个生态的一部分,比如pme适合GUI,async适合分布异步,微后端化可以被用于嵌入编程,而唯有C系才能进入系统内核编程:内核空间与用户空间的编程环境非常不一样只支持C语言这就将任何基于脚本的原型语言和设计排除在外。静态编译类语言安全,而解释脚本类开发时效率高但不安全不能用于高精密领域,语言的逻辑热更新,编译型语言也能办到,这与语言是什么属性毫无必然关系,------ 这些都是语言与其它三栈无层次联系的几个例子,代表了它们的适用领域和人群需求,发明初衷)

(2)另一种方向是统一后端,如jvm体系,clr体系,各种技法和语言前端也被分散在了前端语言中,如jvm上不但有java也有jpython,clr上也有多种语言,这种统一后端方向的融合工作也没错。相比统一后端,统一前端要复杂得多才是真本事,真根本。这样的结果是仅出现多种语言,但是生态得到了极大简化(比如问题域统一/库抽象比较统一可以多语言共享)。

这二种融合方向,其实都基于一种最基本的事实和本质:随着新出现的业务需求和人的要求,任何语言都需要不断DSL化。而任何语言,它们的内部和外部扩展能力。都是这门语言出生时的“最小使命”,来归纳一下现今现语言的元编程能力:

ps: dsl化方向的融合:

语言系统最小应该提供什么,然后才是其它什么东西?即自我扩展的能力:DSL能力和元编程设施 如CPP有范型,这种参数化类型,这使得CPP可以在编译期仅靠语言本身技法就可以实现DSL,辅助程序员完成“库是用来扩展语言的这种说法,但更重要的是需要语言本身也可以扩展自己”,另外二个运行期语言系统的对比,就是js和py了。js可以在语法技上用函数机制直接在抽象ast上写程序(任何语言机制都可以用函数抽象达成,而且这种抽象受语言核心支持,都可变成一级对象)具备元语言能力。而py可以用“meta object”之类的语言级抽象来提供元语言能力,辅助程序员完成“库是用来扩展语言的这种说法语言自身也可以”,后二者在运行期追求语言结构的变化(比如内省,这对GUIprogramming抽象亲和但不够安全),提供灵活性,但有得有失,不够安全也增加了运行期的维护调试成本。这是 cpp/rust vs js,py这二门派语言在借助编译器提供DSL能力上的显式区别。------ 否则。为了完成以上目的,语言需要提供显式化的“用语言本身来发明语言”,需要使得语言本身被服务化,可以被作为库调用。比如像terralang,racket-lang(A programmable programming language,language oriented programming language)。这种显式宣称自己有DSL能力的语言。---- 但是它们将这种能力放到了语言设施外。

但是,无论如何,上面的任何一种,都是”语言系统“级别的融合,其实这都使得语言学习成本增多。没有统一学习法,一门语言应该核心稳定,为了长久的应用或学习曲线,,,但是开头说了,业界从来都是先把想到好用的先用起来,再慢慢解决不那么重要的麻烦事。即融合使之进入同一个生态更好用。

那么能不能改变开发中的其它三栈行为,使得语言跨域实现oneforall呢(如同上面的lang本身DSL化一样)?

appmodel融合:语言外对语言融合的要求与实现
业界终于想到对融合APPMODEL下手了。这就是上面不那么重要的麻烦事之一。

我们知道,到现在为止,我们的常见领域主要有欠入式os实现类/native/web领域,语言都宣称它们是通用类,但实际上都被设计成领域实用和领域适用。现实中语言无论上面提到的哪一种,其实都可以DSL无限化,但都是在一种语言生态内完成的都不能跨应用域,那么有没有真正跨域的语言呢,实现语言真正的one for all?比如最难攻克的native/web融合....

分布式应用现在最典型的就是web,很难为分布式框定APPMODEL,因为这是一种跨OS跨进程的“APP”,---- 分布,是一种产品分离,也是抽象的一种,同时关乎产品设计和语言程序设计,可以用多种方法来达成。web就是一种。但是这种领域不能做本地计算密集的游戏应用。而且要求的语言跟nativedev大相径庭,那么有没有让他们共享同一种语言系统呢?

PS:the web api/service and serverside/cliside web programming essentials

web作为业界分布式程序的第一种广为流传的尝试和成功案例,其实它带来的误导性和建设性(支持页面链接,碎片化程序发布即page app)一样多,web误导了真正的分布式很多年。使得plan9和x11这类原生分布式都失败,单就其bs web技术选型中的浏览器技术,基本用可编程的clientside UI(js->page)代替了app ui,一条道走到黑。先不说这个,

现在的web/webstack技术中,服务端的主要任务主要集中在MVC框架内的东西,即数据方面orm协议方面url regex route/request/respone模板template filter,包括了部分客户端逻辑,这部分客户端逻辑可以完全交给客户端来做。服务端即MC。客服之间交互的,或者是request/respone这种传统带状态的协议,或者post json作为请求的webapi。 至于客户端方面,就是一个可编程的v8 render,。web编程的协议本质是对request/respon编程,所以这是客户端和服务端共同的,客户端还主要负责DOM编程(以后扩展的webcliside技术还有很多~~),,有jquery,pwa,react,ajax这些客户端技术来与服务端的api交互。综合完成webapp的效果(会前后端开发的叫全栈)。我们讨论的就是这种前后端分离的web编程。区别于传统页面跳转无状态的方式。-—— 这种api和面向微服务的web开发特征是:将gui分离出去。web就有了类native的appstack和mvc,,前后端分离,仅靠一条api地址和参数交互,就分离了本地和分布式最根本的问题。各具体组成栈最大解偶,任何app,不要把gui作为框架和app栈的一部分。后端只需负责services。把写业务,和写界面的语言和生态分开。

对于可编程的web的要求,是为其装配某种web可用的语言件api供人们使用,这样才能接上语言和开发,而web是现在唯一的真正的跨端跨OS跨设备跨语言的编程模型和appstack,这也是它API方面的要求:历史上,这些web api,web service技术其实很早就出现,最初它们是在本地做的,为了达到分布式跨一切的效果,以前是利用各种rpc/rmi技术规范给本地语言导出的web函数建一个调用方的本地桩,使之分布式和组件化,这种rpc webservice越做越复杂就淘汰了,因为脚本语言出现了带来了源码即组件的概念:即通过虚拟机语言往往是跨平台的特性,一方面使得web服务本身并没有任何来自OS的载体webapi纯粹脱离本地平台化API,,另一方面分布式要求开发件和发布件一体,脚本语言刚好src api即web runtime一体,在编程上可作为虚拟机语言的脚本源码组件代替传统API桩的作用,而所谓API桩 ---- 其作用相当于一种语言或平台port给另一种语言或平台的代理和转接逻辑,为了API而设的wrapper api,一个类比例子是软件方面的桩,如x11server,它实质是部署在客户端的server。真正在服务端的是显示服务器,所以这种x11 remote app本质也是一种分布GUI的APP(跟webbrower一样),plan9的分布FS协议也是,而我们传统的WEB是另起灶炉设计的,这就是我们第一句话讲到的web的误导作用,误导了真正的在OS级直接提供原生分布式服务的架构发展,曾经为了web跟nativeapp接近搞出了ajax,websocket,wetbgl,好了不说它了,都是泪。

这就是说,web开发和nativedev天然断层,完全不搭。下面是业界对他们的融合之法:

为了达到使用同一语言能领域开发融合,需要针对appmodel栈中的平台,应用规范,整合具体语言针对的领域。或者作广泛意义上的appmodel融合。

(1) 作为融合能多领域开发的语言的例子,业界能做到这点的唯二的二种是go和rust:

比如对于跨web,native的开发,可以不改造既存语言和它们的生态,却综合它们的生态,也使语言建立层次。就如同c之于汇编一样,使新语言提升到高阶。比如,正如c是汇编的高级语言,rust是c/javascript的高级语言(视c/js为高级汇编,c,js都是基础语言代表二个平台。而go,rust这类都是主语言),rust/go是可以转译到低级语言javascript或c的。现在这种转译语言语言还非常流行,比如typescript可以转译到js,elixer可以转到haskell.这样就统一了语言针对的领域。

(2)为了进一步统一native/web,于是就有了emscripten和asm.js这种东西(在浏览器沙盒中甚至都可以运行linux,和qemu虚拟机,当然这些目前都是实验性质的)。再来看wasm,WebAssembly 不仅可以运行在浏览器上,也可以运行在 非web环境下。非Web环境可能包括JavaScript虚拟机(例如 node.js)。但是,WebAssembly 也被设计为能够在没有 JavaScript 虚拟机的情况下运行。这基本是浏览器中搞nativeapp,而且绕一层js,它还有一个意义:让前端支持cpp等语言,使js不再是前端唯一语言。只不过目前wasm仅是用来辅助js的一个扩展,而业界甚至也搞出了纯wasm的前端.

以上这2点,类似语言的DSL融合合,但又是关乎appmodel融合的。其实都是最终appmodel对语言要求的侧影。因为开头就说过,语言会提供什么技法,都可以被归结为“语言技法与问题域结合处的那些东西,要求语言提供某些特定的习惯用法与设计模式:如frp,pme能很好GUI和异步,mvc能很好处理WEB框架”,语言技法和领域都会让语言呈现变化一样。
作者:Minlearn