語言的作用
語言的作用是為了交流想法,描述概念贬墩,
當(dāng)前使用了什么語言榴嗅,取決于我們有什么樣的需要。
為了理解詞法作用域陶舞,閉包嗽测,和continuation,
前文中,我們借助了Racket唠粥。
現(xiàn)在疏魏,為了理解代數(shù)數(shù)據(jù)類型(algebraic data type),多態(tài)(polymorphism)晤愧,參數(shù)化類型(parameterized type)大莫,類型類(type class),我們要學(xué)習(xí)Haskell了官份。
編程也是如此只厘,它是關(guān)于思想的,
編程語言只是描述這種思想的工具罷了舅巷。
非嚴(yán)格語義(non-strict semantics)
在Haskell規(guī)范中羔味,并沒有要求使用惰性求值策略(evaluation strategy),
只是規(guī)定它是一種非嚴(yán)格的語言(non-strict language)悄谐,
具體的求值策略取決于實現(xiàn)介评。
那么,什么才能叫做non-strict呢爬舰?
non-strict與lazy有什么關(guān)系呢们陆?
還要從數(shù)學(xué)上函數(shù)的嚴(yán)格性(strictness)說起。
程序中的function與數(shù)學(xué)函數(shù)之間的關(guān)系情屹,
是指稱語義中的內(nèi)容坪仇。(指稱語義是形式語義的一種,它將每一段代碼垃你,與一個數(shù)學(xué)對象相對應(yīng)椅文,用來研究程序的含義。
在數(shù)學(xué)上惜颇,如果一個函數(shù)對定義域中的某些參數(shù)皆刺,沒有定義值,
就稱為該函數(shù)為部分函數(shù)(partial function)凌摄。
程序中的function羡蛾,對應(yīng)著數(shù)學(xué)上的部分函數(shù)。
此外锨亏,程序中某一類型的全體值痴怨,也不能簡單的對應(yīng)于數(shù)學(xué)上的集合,
例如器予,程序中的全體整數(shù)類型的值浪藻,并不對應(yīng)于整數(shù)集,
因為返回整型值的function乾翔,取某些參數(shù)時爱葵,程序可能不會終止。
為了給這樣的function和返回值找到指稱,
我們給每個集合增加一個新的值:⊥
钧惧,讀作bottom暇韧。
f(⊥) = ⊥
一個數(shù)學(xué)函數(shù),如果參數(shù)是⊥
浓瞪,那么結(jié)果就一定是⊥
,
這樣的函數(shù)稱為嚴(yán)格函數(shù)(strict function)巧婶。
反之乾颁,如果參數(shù)包含⊥
,但是結(jié)果不一定是⊥
艺栈,
這樣的函數(shù)就稱為非嚴(yán)格函數(shù)(non-strict function)英岭。
如果程序語言中function的指稱語義是非嚴(yán)格函數(shù),
那么這樣的語言湿右,就稱為非嚴(yán)格的語言(non-strict language)诅妹。
注:
嚴(yán)格性是指稱語義中的概念,而求值是操作語義中的概念毅人。
并且指稱語義對于操作語義具有可靠性(soundness)吭狡,
即,如果一個表達(dá)式根據(jù)操作語義求值為另一個丈莺,那么划煮,它們必定具有相同的指稱。
因此缔俄,對于non-strict language弛秋,求值策略可能并不唯一,
對Haskell來說俐载,GHC是最流行的編譯器蟹略,
它使用了惰性求值(lazy evaluation)。
在沒有歧義的情況下遏佣,人們常用lazy暗指non-strict挖炬,
lazy更直觀更有利于溝通。
引用透明性
An expression is said to be referentially transparent if it can be replaced with its corresponding value without changing the program's behavior.
即贼急,引用透明性(referential transparency)指的是茅茂,
程序中的表達(dá)式總是可以用它的值來代替。
而程序中的純函數(shù)(pure function)太抓,指的是空闲,
(1)這個函數(shù)對相同參數(shù)總是輸出相同結(jié)果
(2)這個函數(shù)沒有副作用(side effect)
因此,純函數(shù)具有引用透明性走敌。
此外碴倾,語言采用了惰性求值,意味著表達(dá)式的求值方式是按需確定的,
所以跌榔,依靠副作用來得到計算結(jié)果就不可行了异雁,
我們不知道計算在什么時候發(fā)生。
因此僧须,一旦語言擁抱了惰性求值纲刀,就不得不保證引用透明性,
反之則不一定担平,具有引用透明性的語言示绊,可能不必是惰性求值的。
至于暂论,純函數(shù)是不是解決問題的最佳方式面褐,目前尚無定論,
但至少它是為了追求優(yōu)雅性取胎,對通常編程方式的一種挑戰(zhàn)展哭。
歷史上的純函數(shù)式惰性語言
在20世紀(jì)70年代末,Gerry Sussman和Guy Steele發(fā)明了Scheme闻蛀,它是Lisp的一個方言匪傍,與lambda演算很相似,并支持了詞法作用域循榆。
幾乎同時析恢,Robin Milner為了進(jìn)行自動定理證明發(fā)明了ML,其中使用了多態(tài)類型系統(tǒng)秧饮。
但是Scheme和ML都是基于嚴(yán)格語義的語言(strict language)映挂。
到了80年代,人們?nèi)计鹆藢Ψ菄?yán)格語義的(non-strict)盗尸,或者說是按需求值的(call-by-need)函數(shù)式語言的研究熱情柑船。
這方面的研究理所當(dāng)然的吸引了很多人,首先泼各,函數(shù)式語言簡單而優(yōu)雅鞍时,其次,惰性(lazy)與引用透明性有關(guān)扣蜻,并且還可以處理無窮長的數(shù)據(jù)結(jié)構(gòu)(infinite data structure)逆巍。
在80年代中期,很多研究者都想設(shè)計實現(xiàn)一個純函數(shù)式的(pure)惰性語言莽使,Miranda和Lazy ML是其中的兩個例子锐极。
1987年波特蘭FPCA'87會議之后,與會者想發(fā)明一種尚未命名的新語言芳肌,
其實一開始灵再,人們想從一門現(xiàn)有的語言開始肋层,逐漸發(fā)展迭代,比如說翎迁,使用當(dāng)時最成熟的Miranda栋猖。
Miranda是David Turner的公司Research Software Limited開發(fā)的一門語言,它是惰性求值的汪榔,包含代數(shù)數(shù)據(jù)類型蒲拉,使用了Hindley-Milner類型系統(tǒng),從1985年起用于商業(yè)中揍异。Miranda有很好用戶接口全陨,對實現(xiàn)的支持良好,還有大量的教材衷掷。
可是,與David Turner溝通后柿菩,他拒絕了這件事戚嗅。
我們想要一門用于研究語言特性的語言,因此我們決定任何人都可以擴(kuò)展和修改語言本身枢舶,重新實現(xiàn)或者發(fā)行懦胞。但是David Turner想維持一份語言規(guī)范,讓語言具有最好的可移植性凉泄,他不想讓Miranda出現(xiàn)各種不同的方言躏尉。
于是,Haskell的故事就這樣開始了后众。
參考
A History of Haskell
Non-strict semantics
Lazy Evaluation of Haskell
Foundations for Programming Languages