天天看點

程式設計語言選型之技法融合,與領域融合的那些套路

本文關鍵字:oneforall 程式設計語言真的存在嗎,多語言統一學習法,統一native/web語言和領域,the web api/service and serverside/cliside web programming essentials

在以前的文章《語言選型通史:快速整合産生的斷層》中,我們一直讨論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架構”,語言技法和領域都會讓語言呈現變化一樣。

下一文《盤點語言技法與問題域結合處的那些習慣用法與設計模式1,2,3》

(此處不設回複,掃碼到微信參與留言,或直接點選到原文)

程式設計語言選型之技法融合,與領域融合的那些套路