racket不同于別的語言,它是一門可編程的語言。其首頁上萬年不變的一行大字A programmable programming language已經(jīng)說明了一切。
當(dāng)我們處理一個復(fù)雜編程問題時(shí),如果是一般的編程語言,我們只能設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)或類,然后編碼實(shí)現(xiàn)方法。但是這一切在racket中都變了,我們首先要做的是設(shè)計(jì)一門最適合解決這個問題的語言,實(shí)現(xiàn)語言,然后實(shí)現(xiàn)解決問題的方法。
為什么這么說,這得益于racket中的源代碼解析過程。在racket程序運(yùn)行前,會經(jīng)歷兩個運(yùn)行前過程:read和expand,分別對應(yīng)于讀取期和編譯前,read可以將任意的輸入字符解析為語法樹,expand則任意修改語法樹,最后編譯器進(jìn)行編譯,解釋器執(zhí)行。也就是說,我們可以在兩個階段改變編譯器看到的東西。這就是可編程編程語言的威力。
racket的reader是一個遞歸下降的解析器,它可以經(jīng)一個readtable和各種參數(shù)進(jìn)行配置。這個readtable定義了很多分隔符和特殊字,比如:
數(shù)據(jù)單元的開始
如何解析#開頭的數(shù)據(jù)
number和symbol的分隔符
開閉括號
第一個列表元素后的 .
不過這個我們一般不更改,除非想定義出一門完全嶄新的語言,我們還是不要太標(biāo)新立異,我們一般只考慮默認(rèn)的readtable。
從一個流中讀取產(chǎn)生一個一個datum(數(shù)據(jù)單元),如果是個復(fù)合數(shù)據(jù),那么遞歸調(diào)用reader去讀取其中的數(shù)據(jù)單元。