閱讀更多
毫無疑問,不同的編程語言間存在著很多差異性。那么對于這種差異性開發者應如何解決?本文就來一探究竟。

以下為譯文:

我一直在告訴別人:“編程非常了不起?!痹諛閿腥魏蝸敕ǖ氖焙?,都可以編寫軟件,然后愿望就實現了。這很真實。與建立物理的東西不同,首先你需要建立整個工廠,而軟件的擴張相對非常容易。你可以找到所有已經編譯好的組件,而且是免費的,拿來就可以用。建立好一段代碼后,就可以重復使用無數次,而無需花錢。聽起來很厲害的樣子。

但有時候不是這樣的。編程帶給人的驚喜只是暫時的。在建立了很多代碼以后,在寫代碼的過程中你會不斷遇到讓人迷惑的錯誤。一旦你習慣了特定語言和框架的模式后,一旦你需要第二種天性去掌握所選語言中非自然的語法時,編程的偉大之處就不復存在了。

更別提我們有無數種不同的編程語言。每當開發人員面對特殊語言的語法而深感沮喪時,他們都會想“為什么我們不能創建一種新的語言改正這個問題呢?”有些人還真的這么做了,很幸運的是自然選擇已經淘汰了很多很差的語言(有時也有意外,比如至今PHP還存在)。一旦一門新的語言開始在一群開發者中流行起來,那么恭喜你 ,現在又出現了一個新的開發者社區,他們互相合作,努力讓這門特殊的語言發展壯大。

每一種新語言的誕生所帶來的創新,都能造福我們每一個人。但是有時也有不利的一面。有些人可能寫了一些非常有用的開源JavaScript庫,但是從事Python的開發者卻完全沒法用。他們不得不自己寫一個Python版本的函數庫,或者用JavaScript重寫所有代碼。再想想當前有多少種語言和框架。如果你不覺得這很荒謬的話,那只能說明或許你在軟件開發這一行太長時間,已經習以為常了。

語言都包含些什么?

各種編程語言都在以下三個方面上有著很大的不同:語法、語義和標準庫。

沒錯,我知道,我過于簡化它們了,但是聽我給你解釋。

1. 語法

如果不遵循語法,那么你會在編輯器中看到各種彎彎曲曲的紅線,而且你的代碼也無法通過編譯器或解釋器。

JavaScript使用大括號,布爾型使用小寫的true和false,用//表示行注釋。
function doSomething() {
  a = true;
  if (a) {
    ... // Do something.
  }
}

Python用縮進,布爾型用首字母大寫的True和False表示,用#表示行注釋。
def doSomething():
  a = True
  if a:
    ... # Do something.

Haskell又有完全不同的語法:
doSomething :: IO ()
doSomething = do
  let a = True
  if a
    then ... -- Do something.
    else return ()

2.語義

所有編程語言都有大多數相同的特征:變量賦值、數字相加、字符串操作、調用函數、等等。

然而,每種語言都有特殊的思想,以特定的方式運行??梢越腔殖剎煌哪J劍釷?、面向對象、函數式),但是即便是兩個相同模式的編程語言在細節上也是完全不同的。

在“聲明類”,“調用函數”,或“定義參數的類型”時,你定義了程序的語義。有些語言遵循這樣一套規則,而其他的遵循別的規則。比如:C++中聲明的類可以延伸到多個類。當你使用“+”將數字和字符串加到一起的時候,根據語言的語義會得出不同的結果。一些編程語言會因為類型不匹配而導致編譯失敗,但是有些編程語言會自動將數字轉換成十進制的字符串。

語法與語義的關系就相當于用單詞(語法)來表達想法(語義)。你可以通過語言的語法來表達語義。

3.標準庫

最后,每種語言都有各自的軟件包,我們稱之為“標準庫”。

在Python中,你可以調用如下函數:
  • print():在控制臺輸出信息
  • len():返回數組的長度
  • 以及各種實用的???,例如:json,threading,等等
在JavaScript中,你可以使用console.log()代替print(),可以訪問Object、Array等類。

標準庫是一門語言中重要的組成部分。它可以為語言帶來活力,沒有標準庫,你無法簡單地做出任何東西。

很諷刺的是,并沒有“標準的標準庫”。每個標準庫基本上都不同于其他庫:一些庫只提供最低限度的方法,而有些庫則提供非常廣泛的函數,所以開發人員基本上不需要依賴任何第三方庫。

基本的想法

以上我們介紹了一門語言的構成,接下來我有一個基本的想法:我們是否可以找到一種方法清晰地分割語法、語義和標準庫呢?我們又如何實現這一想法呢?

第一步:只有程序員關心語法

我想解決的第一個問題就是語法。編譯器和解釋器擁有更加有效的方式表現代碼,我們稱之為抽象語法樹。我們用代碼描述的內容最終可以用如下抽象語法樹表示:

圖:歐幾里得算法的抽象語法樹

如果仔細觀察,你會發現上述語法樹可能來自多個語言。是Python?是JavaScript?還是C++?這都無所謂:所有這些語言都擁有同一個語法樹。

當然,現實的例子會更加復雜。這就是為什么我們用文本寫代碼的原因:更加緊湊,更加易于書寫,還有更加易于閱讀(有人可能有不同的看法)。從編程誕生的第一天,我們采用的就是這種方法,很少有人對此質疑。

對于一個更加現實的例子來說,抽象語法樹會描述所選語言的語義(例如:類的定義)。但是擁有類似語義的語言之間還是可以共享同一個抽象語法樹,并可以擴展到一定范圍。這非常實用,因為你可以自動轉化部分代碼。

所以,我們可以把語法想象成抽象語法樹之上的人類思維。代碼可能并不會以文本的形式存儲在任何地方,僅在文本編輯器內。如果你想在特殊的語言上使用不同的語法,也完全可以。這不會影響到別人。

我其實有點驚訝怎么沒有一種工具可以將代碼從一種語言轉換成另一種語言,這完全可行啊。我猜肯定有人試過,但是放棄了,因為如果不將整個標準庫轉換過去的話是沒有實用性的。很明顯,我也在做這方面的嘗試。

第二步. 將標準庫抽象成API

API是一個非常高明的概念。每個軟件都可以通過API與其他軟件溝通。移動端的應用可以通過API與服務器交流。服務器可以通過API與數據庫交流。每個人都可以通過API與他人對話。這是一件很酷的事情。

為什么我要在這里討論API?因為這正是我們所需要的。API是語言的媒介。它們是一套語義,可以描述一個特殊代碼??槎醞馓峁┑墓δ?。無論是函數庫,HTTP服務器,或是別的。

聲明API的方式多種多樣??梢允荖PM上的JavaScript???,并在README文件內提供API文檔。也可以是代碼中明確聲明的API,比如TypeScript???。也有可能并沒有API的聲明,也沒有清晰的文檔。

但是重要的是:API聲明了代碼??櫚摹倍醞飩涌凇?,你可以用其他語言重寫??檳誆康拇?,但API不會發生改變。這就是API的魅力所在。雖然編程語言一團糟,但是API很酷。

前面我們提到了標準庫,并說了各個語言都擁有完全不同的標準庫。如果我們能想個辦法將標準庫抽象出來,做成干凈利落的API,那么我們就可以解決這個問題。雖然在語義上,調用print("Hello")與Java調用System.out.println("Hello")不同,但是其實它們可以是同一個API。

我們有兩種方法可以解決這個問題。要么我們讓大家都不要再使用標準庫了,轉而使用我們的“API層”?;蛘呶頤強梢勻眉撲慊遠貧夏閌褂玫拇?。我并不看好“說服大家改變他們的方式”,所以我會選擇后一種方法。

我們不用為編程語言的標準庫中的每個函數都提供API。一般我們只可能用到標準庫中的幾個函數。我們可以自動將這些代碼從一種語言轉換到另一種語言。然后,我們只需要每個開發都用這些API替換具體的標準庫的調用。不用擔心,計算機依然需要你,至少現在需要。

第三步:把所有東西都做成API

現在我們有了干凈的代碼??槎ㄒ宓拇看獾撓鏌?,并將與標準庫的交互抽象成了API。

下一步做什么?創建API。

現今的代碼庫有多個文件構成,彼此之間通過“import語句”互相引用。這對于我們來說很便利,但是這也意味著我們需要在腦海中勾畫代碼庫的結構。任何一個地方發生小的變化,都可能在不經意期間給別的地方帶來破壞性的影響,尤其是如果我們沒有做好自動測試的話。而且,代碼庫會不斷增長,而編譯的時間會逐漸加長。

也許有更好的方法解決這個問題。比如??榛褪歉齪冒旆?。

我之前寫過關于??榛奈惱攏ǖ慊髡飫鋝榭矗篽ttps://medium.com/@fwouts/the-zenc-master-plan-c693bf3b265e),基本上來說:每段獨立的代碼都應該抽象成API。我稱之為???。你無需在意一個具體的??槭褂檬裁從镅員嘈吹?。在寫??櫚氖焙?,你不用導入這些文件。實際上,這時文件已不復存在。你可以直接使用API,它們會自動加載這些功能。

??橛惺裁春么??
  • 可以鼓勵大家考慮設計:首先你需要設計API
  • 可以降低認知的開銷:你僅需要“填空”
  • 簡化測試:你只需測試API,并可以模擬所有的依賴性
  • 世界會變得更加美好:沒有了語言之間的壁壘,沒有了巨大的代碼庫;程序員更加快樂,客戶更加快樂
第四步:盡情享受

我不確定第三步之后會發生什么,但是我覺得所有人都會很滿意。
  • 大小: 341.7 KB
  • 大小: 91.3 KB
來自: CSDN資訊
3
0
評論 共 1 條 請登錄后發表評論
1 樓 aa87963014 2018-07-24 09:42
非常贊同,現在的語言太多了語法又差異太大增加無謂的學習成本很惡心

發表評論

您還沒有登錄,請您登錄后再發表評論

相關推薦

  • 怎樣解決編程語言之間差異性問題?(轉載)

  • 淺談編程語言之間的區別

    1、shell程序 windows的shell叫做cmd,它會運行.bat的batch文件。Linux中的shell程序被稱為bash或者sh。shell程序的問題在于程序超過百行之后擴展性差,并且比其他語言的運行速度慢很多。 2、C和C++語言 極其重視性能的時候使用,它們有許多細節需要自己處理,處理不當就會導致程序崩潰和其他難解決的問題。而C++和C看起來很像,但是特性完全不同。 ...

  • 通過一個簡單的數學游戲,清晰了解各大編程語言之間的一些區別

  • 幾個JavaScript的瀏覽器差異處理問題

    原文鏈接://www.nowamagic.net/librarys/veda/detail/1507 JQuery確實是個很好用的庫,你可以不用考慮很多細節方面的事情。但很作為一個web前端,處理和了解瀏覽器差異一個重要問題。下面將介紹一些總結,先介紹沒有使用js庫的情況。 1. setAttribute方法設置元素類名 在jQuery中,直接使用attr(

  • https://blog.csdn.net/xiangxizhishi/article/details/78840214

    ?? 摘要: 本篇主要學習在Scala中使用條件表達式、循環和函數,你會看到Scala和其他編程語言之間一個根本性的差異。在Java或C++中,我們把表達式(比如3+4)和語句(比如if語句)看做兩樣不同的東西。表達式有值,而語句執行動作。在Scala中,幾乎所有構造出來的語法結構都有值。這個特性使得程序更加精簡,也更易讀。本篇的要點包括: 1. 表達式有值 2. 塊也有值,是它最后一個表

  • 瀏覽器之間樣式差異———解決

    做前端開發,調試是必不可免的。鑒于谷歌強大的調試工具,一般開發還是用谷歌瀏覽器做調試比較好。 但谷歌有利也有弊,因為谷歌有自動補全機制,所以有些錯誤我們還是要借助其他瀏覽器來進行調試。 瀏覽器之間內核不一樣,的確會存在差異,如果真的是內核之間大的差異引起的,那就沒辦法了。但是也有可能是默認樣式引起的,因為瀏覽器之間的默認樣式也不一樣。一般都會引入重置樣式盡量消除瀏覽器之間差異??梢砸雗orm

  • https://blog.csdn.net/iteye_20927/article/details/81898590

    同志們,朋友們,戰斗在java前線的同胞們,關于兩個不同系統間大數據量交互你們在開發中是如何處理的。我先說說我們的處理方式吧?;隊蠹姨岢齦玫?em class='related_suggestion_highlight'>解決方案。 首先,有兩個系統之間要交互數據,一分鐘可能高達數千條或更多(視用戶訪問量而定)的數據量。我們現在的做法是采用socket同步兩系統間的數據,但這樣根本就忙不過來。如果采用webservice更不合適更慢,請大家說說你們在系統中是如何處...

  • Cache 一致性問題解決思路

  • C++虛基類解決二義性問題及執行結果分析

    由于C++中允許多繼承,所以會出現二義性問題:在多個派生類中,定義了相同名字的方法,這時再在main函數里面通過基類調用該方法時,編譯器就犯難了。因為它不知道你到底是想用哪一個派生類里面的方法。 那么,現在又有了一個問題:假如有兩個派生類DerivedA和DerivedB,它們的同名方法一個有參數,一個沒有參數,是不是不會出現二義性問題了? 或者說,這兩個派生類方法的一個是privat

  • 淺談各類編程語言之間差異

    引 瀏覽各大編程相關的網站, 總是能看到有關于編程語言的爭論, 這些爭論使得想要學習編程的人變得疑惑。?總會讓人陷入到底什么是最好的編程語言, 我該學什么, 這樣的疑問中。 我曾經也陷入過這樣的疑惑中, 入行做“碼農”大概也有一年半的時間了, 借著2018的過去, 2019的開始, 嘗試總結一下這類問題, 給過去的疑問一個交代, 給新人一份細微幫助(但愿)。 機器碼編程(匯編語言) 匯編語言...

  • https://blog.csdn.net/SuperVictim/article/details/50448685

  • 9.并發編程的三個概念(原子性、可見性和有序性)存在的問題及其解決方案

  • 各類編程語言對比

    C 誕生在計算機系統結構時代,是用于寫操作系統的語言 重點:指針、內存、數據類型 語言本質:理解計算機系統結構,使得編寫的程序效率更高(內存更?。? 解決問題:性能 適用對象:計算機類專業,底層程序的開放 Java 誕生在網絡和視窗時代 面向對象,進一步抽象,使得代碼復用更靈活 用跨平臺方法解決跨平臺問題 重點: 對象、跨平臺、運行時 語言本質:理解主客體關系 解決問題:跨平...

  • 解決緩存與數據庫一致性問題

  • Stata - 內生性問題:處理方法與進展

    ……Stata 連享會精彩推文…… 【在線觀看】連玉君 - 內生性問題:處理方法與進展 相關鏈接 IV 估計 DID-倍分法 ……Stata 連享會精彩推文…… 關于我們 【Stata 連享會(公眾號:StataChina)】由中山大學連玉君老師團隊創辦,旨在定期與大家分享 Stata 應用的各種經驗和技巧。 公眾號推文同步發布于 【簡書-Stata連享會】 和 【知乎-連玉...

  • 如何解決不同瀏覽器之間的兼容性問題

    常見的瀏覽器兼容性問題解決方案大致有以下九種形式:?   一、不同瀏覽器的標簽默認的外邊界和內填充不同   問題表現:不加樣式控制下,margin和padding差異較大   解決方案:css里 *{margin:0; padding:0;}   備注:這是最常見也是最易解決的一個兼容問題,幾乎所有的css文件開頭都會用通配符*來設置各個標簽外邊界和內填充為0

  • 不同瀏覽器之間的一些差異整理(持續更新ing)

  • 多重繼承引發的二義性問題解決方法分析

  • 分布式環境下的數據一致性問題的討論

    由于互聯網目前越來越強調分布式架構,如果是交易類系統,面臨的將會是分布式事務上的挑戰。當然目前有很多開源的分布式事務產品,例如java JTA,但是這種解決方案的成本是非常高的,而且實現起來非常復雜,效率也比較低下。對于極端的情況:例如發布,故障的時候都是沒有辦法保證強一致性的。首先,在目前的互聯網應用中,我們通過一個比較常見的例子,讓大家更深入的了解一下分布式系統設計中...

  • 分布式系統一致性問題和一致性算法

    一致性問題 一致性算法是用來解決一致性問題的,那么什么是一致性問題呢? 在分布式系統中,一致性問題(consensus problem)是指對于一組服務器,給定一組操作,我們需要一個協議使得最后它們的結果達成一致. 更詳細的解釋就是,當其中某個服務器收到客戶端的一組指令時,它必須與其它服務器交流以保證所有的服務器都是以同樣的順序收到同樣的指令,這樣的話所有的服務器會產生一致的結果,看起來就像

Global site tag (gtag.js) - Google Analytics