當前位置:編程學習大全網 - 編程語言 - 如何評價 Racket 這門編程語言

如何評價 Racket 這門編程語言

Racket的誕生與發展

簡單介紹壹下Racket的發展,詳見?知乎的壹個關於Racket的問題回答?:?

1958年,人工智能之父John McCarthy 發明了壹種以 Lambda 演算為基礎的符號處理語言,1960年 McCarthy 發表著名論文?Recursive Functions of Symbolic Expressions and Their Computation by Machine?, 從此這種語言被命名為 LSIP (List Processor),其語法被命名為:符號表達式(S-Expression)。?LISP構建在7個函數[atom car cdr cond cons eq quote]和2個特型[lambda label]?之上?。

Lisp誕生之初是為了純粹的科學研究,代碼執行像數學公式壹樣,以人的大腦來演算。直到麥卡錫的學生斯蒂芬·羅素將eval函數在IBM 704機器上實現後,才開啟了Lisp作為壹種計算機語言的歷史。1962年,第壹個完整的Lisp編譯器在MIT誕生,從此之後Lisp以MIT為中心向全世界傳播。之後十多年,出現了各種Lisp方言。

1975年,Scheme誕生。Scheme同樣誕生與MIT,它的設計哲學是最小極簡主義,它只提供必須的少數幾個原語,所有其他的實用功能都由庫來實現。在極簡主義的設計思想下,Scheme趨於極致的優雅,並作為計算機教學語言在教育界廣泛使用。

1984年,Common Lisp誕生。在二十世紀七八十年代,由於Lisp方言過多,社區分裂,不利於lisp整體的發展。從1981年開始,在壹個Lisp黑客組織的運作下,經過三年的努力整合後,於1984年推出了Common Lisp。由於Scheme的設計理念和其他Lisp版本不同,所以盡管Common Lisp借鑒了Scheme的壹些特點,但沒有把Scheme整合進來。此後Lisp僅剩下兩支方言: Common Lisp 和 Scheme。

從二十世紀九十年代開始,由於C++、Java、C#的興起,Lisp逐漸沒落。直到2005年後,隨著科學計算的升溫,動態語言JavaScript、Python、Ruby的流行,Lisp又漸漸的回到人們的視線。不過在Lisp的傳統陣地教育界,Python作為強有力的挑戰者對Scheme發起沖鋒;在2008年,MIT放棄了使用Scheme作為教學語言的SICP(計算機程序的構造和解釋)課程,而啟用Python進行基礎教學。同時美國東北大學另立爐竈,其主導的科學計算系統PLT Scheme開始迅猛發展;2010年,PLT Scheme改名為Racket。近幾年,The Racket Language連續成為年度最活躍語言網站,並駕齊驅的還有haskell網站。?

符號表達式 S-Expression

首先說壹下S表達式:?S-表達式的基本元素是list與atom?。list由括號包圍,可包涵任何數量的由空格所分隔的元素,原子是其它內容。?其使用前綴表示法,在Lisp中既用作代碼,也用作數據。?如:1+2*3 ?寫成前綴表達式就是?(+ 1 (* 2 3)) 。

優點:容易parse,簡單純粹,不用考慮什麽優先級等,也是實現代碼即數據的前提;

缺點:可讀性不是很強;

高階函數

高階函數至少滿足下列壹個條件:

接受壹個或多個函數作為輸入;?

輸出壹個函數;

微積分中的導數就是壹個例子,映射壹個函數到另壹個函數。?在無類型 lambda 演算中,所有函數都是高階的?。在函數式編程中,返回另壹個函數的高階函數被稱為Curry化的函數。?Curry化即把接受多個參數的函數變換成接受壹個單壹參數(最初函數的第壹個參數)的函數?,並且返回接受余下的參數而且返回結果的新函數的技術。如 f(x,y)=x+y, 如果給定了 y=1,則就得到了 g(x)=x+1 這個函數。

Lambda 表達式

Racket中實用Lambda表達式來定義匿名函數,《如何設計程序》書中給出的使用原則是:?如果某個非遞歸函數只需要當參數使用壹次,實用Lambda表達式?。如果想用Lambda表達式來表達遞歸,就需要引入?Y組合子?,Y 就是這樣壹個操作符,它作用於任何壹個 (接受壹個函數作為參數的) 函數 F,就會返回壹個函數 X。再把 F 作用於這個函數 X,還是得到 X。所以 X 被叫做 F 的不動點(fixed point),即 (Y F) = (F (Y F)) 。

惰性求值

惰性求值?(Lazy Evaluation),說白了就是某些中間結果不需要被求出來?,求出來反而不利於後面的計算也浪費了時間。參見:?惰性求值與惰性編程?。?

惰性求值是壹個計算機編程中的壹個概念,它的目的是要最小化計算機要做的工作。惰性計算的最重要的好處是它可以構造壹個無限的數據類型。使用惰性求值的時候,表達式不在它被綁定到變量之後就立即求值,而是在該值被取用的時候求值。語句如 x:=expression; (把壹個表達式的結果賦值給壹個變量)明顯的調用這個表達式並把計算並把結果放置到 x 中,但是先不管實際在 x 中的是什麽,直到通過後面的表達式中到 x 的引用而有了對它的值的需求的時候,而後面表達式自身的求值也可以被延遲,最終為了生成讓外界看到的某個符號而計算這個快速增長的依賴樹。?

閉包

閉包在計算機科學中,?閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數?。自由變量是在表達式中用於表示壹個位置或壹些位置的符號,比如 f(x,y) 對 x 求偏導時,y就是自由變量。這個被引用的自由變量將和這個函數壹同存在,即使已經離開了創造它的環境也不例外。在函數中(嵌套)定義另壹個函數時,如果內部的函數引用了外部的函數的變量,則可能產生閉包。運行時,壹旦外部的 函數被執行,壹個閉包就形成了,閉包中包含了內部函數的代碼,以及所需外部函數中的變量的引用。其中所引用的變量稱作上值(upvalue)。網上有很多將JavaScript閉包的文章,如果妳對LISP有系統的了解,那麽這個概念自然會很清楚了。

快排的Racket實現

#lang?racket

(define?(quick-sort?array)

(cond

[(empty?array)?empty];?快排的思想是分治+遞歸

[else?(append?

(quick-sort?(filter?(lambda?(x)?(<?x?(first?array)))?array));?這裏的?array?就是閉包

(filter?(lambda?(x)?(=?x?(first?array)))?array)

(quick-sort?(filter?(lambda?(x)?(>?x?(first?array)))?array)))]))

(quick-sort?'(1?3?2?5?3?4?5?0?9?82?4))

;;?運行結果?'(0?1?2?3?3?4?4?5?5?9?82)

通過這個例子,就可以感受到基於lambda算子的 Racket 語言強大的表達能力了,高階函數、lambda表達式和閉包的使用是Racket所描述的快排十分的精煉,這和 基於馮諾依曼模型C語言是迥然不容的思維模式。後面,隨著Racket 學習的進壹步深入,嘗試寫壹下解釋器

  • 上一篇:中軟卓越的公司大事件
  • 下一篇:vb6.0字符轉換
  • copyright 2024編程學習大全網