智慧合約與函數語言程式設計語言

買賣虛擬貨幣
最近以太坊不是很太平,爆出利用錢包和多重簽名合約漏洞盜取資金的問題,這讓我想起了久違了的函數語言程式設計語言,相比現在流行的過程式語言可能在智慧合約編碼上具有先天優勢


最近的以太坊漏洞現在有文章做了仔細的分析,糾其根本是基於圖靈機的過程式語言與人類邏輯思維衝突的問題,今天就來聊聊函數語言程式設計語言,這個非常古老可能未來會大熱的程式語言體系。


什麼是函數語言程式設計語言


首先,我們要明確函數語言程式設計語言和函數語言程式設計的區別,函數語言程式設計是近來過程式語言吸收函數語言程式設計語言的優點形成的一種程式設計風格,透過框架定義形成的類似函數語言程式設計語言的風格,使得過程式語言(包括面嚮物件語言)具備某些函式式語言的特徵,其核心還是過程式語言。


在計算機程式設計王國裡面有兩個重要語言,一個是C,一個是LISP,都是非常古老的語言。C語言相信大家都不陌生,C語言影響了後來很多語言的發展,包括C++,JAVA,C#,javascritp都可以看做是類C語言的延伸;LISP語言可能很多人就比較陌生了,計算機專業的學生可能聽說過,由LISP派生出的方言,比較有代表性的有CL,Scheme,包括受到LISP語言影響的Haskell,Erlang等(Erlang由於分散式應用,前幾年大熱),可以這樣說C和LISP代表了計算機語言的兩個流派,過程式(也稱為命令式)語言和函式式語言。


這兩個流派的形成要從解決問題的思路說起,我們都知道現在的計算機體系是馮諾依曼結構(儲存轉發結構),馮式結構本身就受到圖靈機的啟發,所以圖靈機非常適合操作這個結構,強調透過有限集合解決機器的問題;而另一個分支是蘭帕德正規化(Lambda),強調直接從解決數學問題入手;於是計算機語言王國誕生了基於圖靈機的過程式語言包括後來發展成為面嚮物件語言,而基於Lambda正規化誕生的就是函數語言程式設計語言。我查到的資料說圖靈機和拉帕德表示式可以相互推導,在邏輯上證明是一致的,所以他們都可以操作馮諾依曼結構的計算機體系。(具體證明過程沒有看到,估計也很難看懂)


總體來說函數語言程式設計語言是一種程式設計正規化,它將電腦運算視為數學上的函式計算,並且避免使用程式狀態以及易變物件。函式程式語言最重要的基礎是λ演算(lambda calculus)。而且λ演算的函式可以接受函式當作輸入(引數)和輸出(傳出值)。


函式式語言的優缺點


其實過程式語言和函式式語言的優缺點必須放在一定場景下才能準確分出其優缺點,就主觀支持者而言,估計吵100年也難分高下;在資深碼農世界存在各種鄙視鏈,每種語言都有其鐵粉,我有一個朋友在學習了Erlang語言後曾經大罵oop(物件導向)耽誤他的技術生命,所以為了避免無謂的爭吵,本文重點強調在區塊鏈智慧合約應用場景下函式式語言的優點。


可能有人要問函式式語言作為一個古老的程式設計正規化,為什麼以前很少聽說,其實瞭解計算機的發展就知道,軟體的發展一直受制於硬體的發展,過程式語言來自最原始的圖靈機模型(讀、寫、跳轉這樣操作),而函式式語言來自 Lambda 函式(符號替換、規約等操作),過程式語言較函式式語言在效能上有先天優勢,所以在硬體能力比較落後的70~80年代,過程式語言的優勢明顯所以,以C為代表的語言得到了充分的發展,同時也影響了後期面嚮物件語言的發展,大學基本上都開設過程式語言的課程,所以大多數人只知道過程式語言,解決問題思路也一直受過程式語言的影響。


但是隨著多執行緒、分散式計算的發展,過程式語言複雜的上下文邏輯,執行緒安全不能得到很好的保證,平行計算開發難度直線上升,於是人們開始從頭找回函數語言程式設計語言,函式式語言變數只與值有關,與物理儲存地址無關。變數與值環境一一對應,這一性質就消除了程式與機器結構的相關性,使得程式設計師在進行程式設計的時候無需考慮計算的操作行為、計算機的狀態變化。只要按照有關語言的語法,用數學或邏輯的方法給出問題的描述和目標即可求解,每一行程式碼都可以是一個獨立的函式,輸入輸出清晰,非常適合多執行緒和平行計算,同時函式式語言更符合人類的思維習慣,在高可靠性場景中,程式碼更容易閱讀和查錯,程式碼執行穩定(Erlang語言就是代表,最早是70年代愛立信開發的交換機語言),所以這些年人們開始重新研究和發展函式式語言,包括近幾年流行的函數語言程式設計風格。


函式式語言的優點

在函式式語言中,由於資料全部都是不可變的,所以沒有併發程式設計的問題,是多執行緒安全的。可以有效降低程式執行中所產生的副作用,對於快速迭代的專案來說,函數語言程式設計可以實現函式與函式之間的熱切換而不用擔心資料的問題,因為它是以函式作為最小單位的,只要函式與函式之間的關係正確即可保證結果的正確性。


函式式語言的表達方式更加符合人類日常生活中的語法,程式碼可讀性更強。實現同樣的功能函數語言程式設計所需要的程式碼比物件導向程式設計要少很多,程式碼更加簡潔明晰。函數語言程式設計廣泛運用於科學研究中,因為在科研中對於程式碼的工程化要求比較低,寫起來更加簡單,所以使用函數語言程式設計開發的速度比用物件導向要高很多,如果是對開發速度要求較高但是對執行資源要求較低同時對速度要求較低的場景下使用函式式會更加高效。

函式式語言的缺點

由於所有的資料都是不可變的,所以所有的變數在程式執行期間都是一直存在的,非常佔用執行資源。同時由於函式式的先天性設計導致效能一直不夠。雖然現代的函數語言程式設計語言使用了很多技巧比如惰性計算等來最佳化執行速度,但是始終無法與過程式語言程式相比。


函數語言程式設計雖然已經誕生了很多年,但是至今為止在工程上想要大規模使用函數語言程式設計仍然有很多待解決的問題,尤其是對於規模比較大的工程而言。如果對函數語言程式設計的理解不夠深刻就會導致跟面相物件一樣晦澀難懂的局面。


智慧合約採用函式式語言的優勢


目前以以太坊為代表的區塊鏈智慧合約中有兩種主要開發語言,

Solidity (類JavaScript 語言)和LLL(類Lisp語言),Solidity和LLL分別代表了過程式語言和函數語言程式設計語言,前文已經談到了函數語言程式設計語言的優勢,由於智慧合約大多不是非常複雜的程式設計,不屬於大型工程,執行效率要求不那麼極端,但要求很高的可靠性和可讀性,因為一旦合約部署直接影響到各方利益,同時合約需要經過利益相關方審計,符合人類思維習慣,直接面向解決問題的函式式語言更加合適。


智慧合約使用函式式語言還有一個優點就是避免造成邏輯歧義,這好比日常的合同,同一段文字表達可能形成兩種完全不同的解釋,如果未來誕生智慧合約律師的話,第三方審計將更容易,可以有效避免邏輯陷阱(比如國外的口是心非C語言程式設計大賽),用C語言的指標呼叫和跳轉可以輕易構造一個邏輯陷阱,這次以太坊合約問題也是因為程式碼邏輯bug被人抓住形成攻擊。


而且蘭帕德數學表示式可讀性高,比如在數學計算中(智慧合約計算各方利益場景)不必考慮常見的先乘除後加減運演算法則,造成不必要的損失,經過簡單學習就能夠看懂Lambda表示式,下面舉個例子:


計算某人一年中每天應該取得的利息和本金合計常用公式為:


(A+A*5%)/365


在過程式語言中如果括號異位寫成  (A+A*5%/365)就賺大發了,而在函式式語言中採用Lambda表示式就很容易識別出來


(/ (+ A (* A 0.05))365)


Lambad表達永遠都是從最內層開始計算,括號成對出現,不必考慮乘除和加減先後的運演算法則,當一個公式非常複雜時,有經驗的程式設計人員可以很輕易構造運算陷阱,有些邏輯bug需要在執行時才會發現(有經驗的程式設計師都知道邏輯bug的查錯難度),這種問題在普通應用中不是問題,但是對於區塊鏈智慧合約來說,一旦部署就會造成難以估量的損失,所以本人認為在智慧合約上推廣函數語言程式設計語言是非常必要的。


來源:區塊鏈大師   微訊號:DACMaster

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;