




已閱讀5頁(yè),還剩26頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
LISP語(yǔ)言教程作者:牛魔王 上次修改時(shí)間: 2007-03-22 13:13 Scheme 語(yǔ)言是LISP語(yǔ)言的一個(gè)方言(或說(shuō)成變種),它誕生于1975年的MIT,對(duì)于這個(gè)有近三十年歷史的編程語(yǔ)言來(lái)說(shuō),它并沒(méi)有象C+,java,C#那樣受到商業(yè)領(lǐng)域的青睞,在國(guó)內(nèi)更是顯為人知。但它在國(guó)外的計(jì)算機(jī)教育領(lǐng)域內(nèi)卻是有著廣泛應(yīng)用的,有很多人學(xué)的第一門計(jì)算機(jī)語(yǔ)言就是Scheme語(yǔ)言。Scheme 語(yǔ)言概要Author:宋國(guó)偉 吉林省德惠市信息中心Date:2003 年 12 月 01 日Scheme 語(yǔ)言是LISP語(yǔ)言的一個(gè)方言(或說(shuō)成變種),它誕生于1975年的MIT,對(duì)于這個(gè)有近三十年歷史的編程語(yǔ)言來(lái)說(shuō),它并沒(méi)有象C+,java,C#那樣受到商業(yè)領(lǐng)域的青睞,在國(guó)內(nèi)更是顯為人知。但它在國(guó)外的計(jì)算機(jī)教育領(lǐng)域內(nèi)卻是有著廣泛應(yīng)用的,有很多人學(xué)的第一門計(jì)算機(jī)語(yǔ)言就是Scheme語(yǔ)言。作為L(zhǎng)isp 變體,Scheme 是一門非常簡(jiǎn)潔的計(jì)算語(yǔ)言,使用它的編程人員可以擺脫語(yǔ)言本身的復(fù)雜性,把注意力集中到更重要的問(wèn)題上,從而使語(yǔ)言真正成為解決問(wèn)題的工具。本文分為上、 下兩部分來(lái)介紹 scheme 語(yǔ)言。一Scheme語(yǔ)言的特點(diǎn)Scheme 語(yǔ)言是LISP語(yǔ)言的一個(gè)方言(或說(shuō)成變種),它誕生于1975年的MIT,對(duì)于這個(gè)有近三十年歷史的編程語(yǔ)言來(lái)說(shuō),它并沒(méi)有象C+,java,C#那樣受到商業(yè)領(lǐng)域的青睞,在國(guó)內(nèi)更是顯為人知。但它在國(guó)外的計(jì)算機(jī)教育領(lǐng)域內(nèi)卻是有著廣泛應(yīng)用的,有很多人學(xué)的第一門計(jì)算機(jī)語(yǔ)言就是Scheme語(yǔ)言。它是一個(gè)小巧而又強(qiáng)大的語(yǔ)言,作為一個(gè)多用途的編程語(yǔ)言,它可以作為腳本語(yǔ)言使用,也可以作為應(yīng)用軟件的擴(kuò)展語(yǔ)言來(lái)使用,它具有元語(yǔ)言特性,還有很多獨(dú)到的特色,以致于它被稱為編程語(yǔ)言中的皇后。下面是洪峰對(duì)Scheme語(yǔ)言的編程特色的歸納: 詞法定界(Lexical Scoping) 動(dòng)態(tài)類型(Dynamic Typing) 良好的可擴(kuò)展性 尾遞歸(Tail Recursive) 函數(shù)可以作為值返回 支持一流的計(jì)算連續(xù) 傳值調(diào)用(passing-by-value) 算術(shù)運(yùn)算相對(duì)獨(dú)立 本文的目的是讓有編程基礎(chǔ)(那怕是一點(diǎn)點(diǎn))的朋友能盡快的掌握Scheme語(yǔ)言的語(yǔ)法規(guī)則,如果您在讀完本文后,發(fā)現(xiàn)自己已經(jīng)會(huì)用Scheme語(yǔ)言了,那么我的目的就達(dá)到了。二Scheme語(yǔ)言的標(biāo)準(zhǔn)與實(shí)現(xiàn)R5RS (Revised(5) Report on the Algorithmic Language Scheme)Scheme語(yǔ)言的語(yǔ)法規(guī)則的第5次修正稿,1998年制定,即Scheme語(yǔ)言的現(xiàn)行標(biāo)準(zhǔn),目前大多數(shù)Scheme語(yǔ)言的實(shí)現(xiàn)都將達(dá)到或遵循此標(biāo)準(zhǔn),并且?guī)缀醵技尤肓艘恍儆谧约旱臄U(kuò)展特色。Guile (GNUs extension language)Guile是GNU工程的一個(gè)項(xiàng)目,它是GNU擴(kuò)展語(yǔ)言庫(kù),它也是Scheme語(yǔ)言的一個(gè)具體實(shí)現(xiàn);如果你將它作為一個(gè)庫(kù)打包,可以把它鏈接到你的應(yīng)用程序中去,使你的應(yīng)用程序具有自己的腳本語(yǔ)言,這個(gè)腳本語(yǔ)言目前就是Scheme語(yǔ)言。Guile可以在LINUX和一些UNIX系統(tǒng)上運(yùn)行,下面是簡(jiǎn)單的安裝過(guò)程:下載guile-1.6.4版,文件名為guile-1.6.4.tar.gz,執(zhí)行下面的命令:tar xvfz guile-1.6.4.tar.gzcd guile-1.6.4./configuremakemake install如此,即可以執(zhí)行命令guile,進(jìn)入guile提示符狀態(tài),輸入調(diào)試Scheme程序代碼了,本文的所有代碼都是在guile下調(diào)試通過(guò)。其它實(shí)現(xiàn)除了Guile外,Scheme語(yǔ)言的實(shí)現(xiàn)還有很多,如:GNU/MIT-Scheme, SCI,Scheme48,DrScheme等,它們大多是開源的,可以自由下載安裝使用,并且跨平臺(tái)的實(shí)現(xiàn)也很多。你會(huì)發(fā)現(xiàn)既有象basic的 Scheme語(yǔ)言解釋器,也有將Scheme語(yǔ)言編譯成C語(yǔ)言的編譯器,也有象JAVA那樣將Scheme語(yǔ)言代碼編譯成虛擬機(jī)代碼的編譯器。三基本概念注釋Scheme語(yǔ)言中的注釋是單行注釋,以分號(hào);開始一直到行尾結(jié)束,其中間的內(nèi)容為注釋,在程序運(yùn)行時(shí)不做處理,如:; this is a scheme comment line.標(biāo)準(zhǔn)的Scheme語(yǔ)言定義中沒(méi)有多行注釋,不過(guò)在它的實(shí)現(xiàn)中幾乎都有。在Guile中就有多行注釋,以符號(hào)組合#!開始,以相反的另一符號(hào)組合!#結(jié)束,其中內(nèi)容為注釋,如:#!there are scheme comment area.you can write mulity lines here . !#注意的是,符號(hào)組合#!和!#一定分做兩行來(lái)寫。Scheme用做腳本語(yǔ)言Scheme語(yǔ)言可以象sh,perl,python等語(yǔ)言那樣作為一種腳本語(yǔ)言來(lái)使用,用它來(lái)編寫可執(zhí)行腳本,在Linux中如果通過(guò)Guile用Scheme語(yǔ)言寫可執(zhí)行腳本,它的第一行和第二行一般是類似下面的內(nèi)容:#! /usr/local/bin/guile -s!#這樣的話代碼在運(yùn)行時(shí)會(huì)自動(dòng)調(diào)用Guile來(lái)解釋執(zhí)行,標(biāo)準(zhǔn)的文件尾綴是.scm。塊(form)塊(form)是Scheme語(yǔ)言中的最小程序單元,一個(gè)Scheme語(yǔ)言程序是由一個(gè)或多個(gè)form構(gòu)成。沒(méi)有特殊說(shuō)明的情況下 form 都由小括號(hào)括起來(lái),形如:(define x 123)(+ 1 2)(* 4 5 6)(display hello world)一個(gè) form 也可以是一個(gè)表達(dá)式,一個(gè)變量定義,也可以是一個(gè)過(guò)程。form嵌套Scheme語(yǔ)言中允許form的嵌套,這使它可以輕松的實(shí)現(xiàn)復(fù)雜的表達(dá)式,同時(shí)也是一種非常有自己特色的表達(dá)式。下圖示意了嵌套的稍復(fù)雜一點(diǎn)的表達(dá)式的運(yùn)算過(guò)程:變量定義可以用define來(lái)定義一個(gè)變量,形式如下:(define 變量名 值)如: (define x 123) ,定義一個(gè)變量x,其值為123。更改變量的值可以用set!來(lái)改變變量的值,格式如下:(set! 變量名 值)如: (set! x hello) ,將變量x的值改為hello 。Scheme語(yǔ)言是一種高級(jí)語(yǔ)言,和很多高級(jí)語(yǔ)言(如python,perl)一樣,它的變量類型不是固定的,可以隨時(shí)改變。四數(shù)據(jù)類型1. 簡(jiǎn)單數(shù)據(jù)類型邏輯型(boolean)最基本的數(shù)據(jù)類型,也是很多計(jì)算機(jī)語(yǔ)言中都支持的最簡(jiǎn)單的數(shù)據(jù)類型,只能取兩個(gè)值:#t,相當(dāng)于其它計(jì)算機(jī)語(yǔ)言中的 TRUE;#f,相當(dāng)于其它計(jì)算機(jī)語(yǔ)言中的 FALSE。Scheme語(yǔ)言中的boolean類型只有一種操作:not。其意為取相反的值,即:(not #f) = #t(not #t) = #fnot的引用,與邏輯非運(yùn)算操作類似guile (not 1)#fguile (not (list 1 2 3)#fguile (not a)#f從上面的操作中可以看出來(lái),只要not后面的參數(shù)不是邏輯型,其返回值均為#f。數(shù)字型(number)它又分為四種子類型:整型(integer),有理數(shù)型(rational),實(shí)型(real),復(fù)數(shù)型(complex);它們又被統(tǒng)一稱為數(shù)字類型(number)。如:復(fù)數(shù)型(complex) 可以定義為 (define c 3+2i) 實(shí)數(shù)型(real)可以定義為 (define f 22/7) 有理數(shù)型(rational)可以定義為 (define p 3.1415) 整數(shù)型(integer) 可以定義為 (define i 123)Scheme 語(yǔ)言中,數(shù)字類型的數(shù)據(jù)還可以按照進(jìn)制分類,即二進(jìn)制,八進(jìn)制,十進(jìn)制和十六進(jìn)制,在外觀形式上它們分別以符號(hào)組合 #b、 #o、 #d、 #x 來(lái)作為表示數(shù)字進(jìn)制類型的前綴,其中表示十進(jìn)制的#d可以省略不寫,如:二進(jìn)制的 #b1010 ,八進(jìn)制的 #o567,十進(jìn)制的123或 #d123,十六進(jìn)制的 #x1afc 。Scheme語(yǔ)言的這種嚴(yán)格按照數(shù)學(xué)定理來(lái)為數(shù)字類型進(jìn)行分類的方法可以看出Scheme語(yǔ)言里面滲透著很深的數(shù)學(xué)思想,Scheme語(yǔ)言是由數(shù)學(xué)家們創(chuàng)造出來(lái)的,在這方面表現(xiàn)得也比較鮮明。字符型(char)Scheme語(yǔ)言中的字符型數(shù)據(jù)均以符號(hào)組合 # 開始,表示單個(gè)字符,可以是字母、數(shù)字或 ! $ % & * + - . / : ? _ 等等其它字符,如: #A 表示大寫字母A,#0表示字符0,其中特殊字符有:#space 表示空格符和 #newline 表示換行符。符號(hào)型(symbol)符號(hào)類型是Scheme語(yǔ)言中有多種用途的符號(hào)名稱,它可以是單詞,用括號(hào)括起來(lái)的多個(gè)單詞,也可以是無(wú)意義的字母組合或符號(hào)組合,它在某種意義上可以理解為C中的枚舉類型??聪旅娴牟僮鳎篻uile (define a (quote xyz) ; 定義變量a為符號(hào)類型,值為xyzguile axyzguile (define xyz a) ; 定義變量xyz為符號(hào)類型,值為aguile xyza此處也說(shuō)明單引號(hào) 與quote是等價(jià)的,并且更簡(jiǎn)單一些。符號(hào)類型與字符串不同的是符號(hào)類型不能象字符串那樣可以取得長(zhǎng)度或改變其中某一成員字符的值,但二者之間可以互相轉(zhuǎn)換。2. 復(fù)合數(shù)據(jù)類型可以說(shuō)復(fù)合數(shù)據(jù)類型是由基本的簡(jiǎn)單數(shù)據(jù)類型通過(guò)某種方式加以組合形成的數(shù)據(jù)類型,特點(diǎn)是可以容納多種或多個(gè)單一的簡(jiǎn)單數(shù)據(jù)類型的數(shù)據(jù),多數(shù)是基于某一種數(shù)學(xué)模型創(chuàng)建的。字符串(string) 由多個(gè)字符組成的數(shù)據(jù)類型,可以直接寫成由雙引號(hào)括起的內(nèi)容,如:hello 。下面是Guile中的字符串定義和相關(guān)操作:guile (define name tomson)guile nametomsonguile (string-length name) ; 取字符串的長(zhǎng)度6guile (string-set! name 0 #g) ; 更改字符串首字母(第0個(gè)字符)為小寫字母g (#g)guile namegomsonguile (string-ref name 3) ; 取得字符串左側(cè)第3個(gè)字符(從0開始)#s字符串還可以用下面的形式定義:guile (define other (string #h #e #l #l #o )guile otherhello字符串中出現(xiàn)引號(hào)時(shí)用反斜線加引號(hào)代替,如:abcdef 。點(diǎn)對(duì)(pair)我把它譯成點(diǎn)對(duì),它是一種非常有趣的類型,也是一些其它類型的基礎(chǔ)類型,它是由一個(gè)點(diǎn)和被它分隔開的兩個(gè)所值組成的。形如: (1 . 2) 或 (a . b) ,注意的是點(diǎn)的兩邊有空格。這是最簡(jiǎn)單的復(fù)合數(shù)據(jù)類型,同是它也是其它復(fù)合數(shù)據(jù)類型的基礎(chǔ)類型,如列表類型(list)就是由它來(lái)實(shí)現(xiàn)的。按照Scheme語(yǔ)言說(shuō)明中的慣例,以下我們用符號(hào)組合 = 來(lái)表示表達(dá)式的值。它用cons來(lái)定義,如: (cons 8 9) =(8 . 9)其中在點(diǎn)前面的值被稱為 car ,在點(diǎn)后面的值被稱為 cdr ,car和cdr同時(shí)又成為取pair的這兩個(gè)值的過(guò)程,如:(define p (cons 4 5) = (4 . 5)(car p) = 4(cdr p) = 5還可以用set-car! 和 set-cdr! 來(lái)分別設(shè)定這兩個(gè)值:(set-car! p hello)(set-cdr! p good)如此,以前定義的 p 又變成了 (hello . good) 這個(gè)樣子了。列表(list)列表是由多個(gè)相同或不同的數(shù)據(jù)連續(xù)組成的數(shù)據(jù)類型,它是編程中最常用的復(fù)合數(shù)據(jù)類型之一,很多過(guò)程操作都與它相關(guān)。下面是在Guile中列表的定義和相關(guān)操作:guile (define la (list 1 2 3 4 )guile la(1 2 3 4)guile (length la) ; 取得列表的長(zhǎng)度4guile (list-ref la 3) ; 取得列表第3項(xiàng)的值(從0開始)4guile (list-set! la 2 99) ; 設(shè)定列表第2項(xiàng)的值為9999guile la(1 2 99 4)guile (define y (make-list 5 6) ;創(chuàng)建列表guile y(6 6 6 6 6)make-list用來(lái)創(chuàng)建列表,第一個(gè)參數(shù)是列表的長(zhǎng)度,第二個(gè)參數(shù)是列表中添充的內(nèi)容;還可以實(shí)現(xiàn)多重列表,即列表的元素也是列表,如:(list (list 1 2 3) (list 4 5 6)。列表與pair的關(guān)系回過(guò)頭來(lái),我們?cè)倏纯聪旅娴亩x:guile (define a (cons 1 (cons 2 (cons 3 ()guile a(1 2 3)由上可見(jiàn),a本來(lái)是我們上面定義的點(diǎn)對(duì),最后形成的卻是列表。事實(shí)上列表是在點(diǎn)對(duì)的基礎(chǔ)上形成的一種特殊格式。再看下面的代碼:guile (define ls (list 1 2 3 4)guile ls(1 2 3 4)guile (list? ls)#tguile (pair? ls)#t由此可見(jiàn),list是pair的子類型,list一定是一個(gè)pair,而pair不是list。guile (car ls)1guile (cdr ls)(2 3 4)其cdr又是一個(gè)列表,可見(jiàn)用于pair的操作過(guò)程大多可以用于list。guile (cadr ls) ; 此點(diǎn)對(duì)對(duì)象的cdr的car2guile (cddr ls) ; 此點(diǎn)對(duì)對(duì)象的cdr的cdr(3 4)guile (caddr ls) ; 此點(diǎn)對(duì)對(duì)象的cdr的cdr的car3guile (cdddr ls) ; 此點(diǎn)對(duì)對(duì)象的cdr的cdr的cdr(4)上在的操作中用到的cadr,cdddr等過(guò)程是專門對(duì)PAIR型數(shù)據(jù)再?gòu)?fù)合形成的數(shù)據(jù)操作的過(guò)程,最多可以支持在中間加四位a或d,如cdddr,caaddr等。下圖表示了由pairs定義形成的列表:這個(gè)列表可以由pair定義為如下形式:(define x (cons a (cons b (cons c (cons d ()而列表的實(shí)際內(nèi)容則為:(a b c d)由pair類型還可以看出它可以輕松的表示樹型結(jié)構(gòu),尤其是標(biāo)準(zhǔn)的二叉樹。向量(vector)可以說(shuō)是一個(gè)非常好用的類型 ,是一種元素按整數(shù)來(lái)索引的對(duì)象,異源的數(shù)據(jù)結(jié)構(gòu),在占用空間上比同樣元素的列表要少,在外觀上:列表示為: (1 2 3 4) VECTOR表示為: #(1 2 3 4) 可以正常定義:(define v (vector 3 4 5) 也可以直接定義:(define v #(3 4 5)vector是一種比較常用的復(fù)合類型,它的元素索引從0開始,至第 n-1 結(jié)束,這一點(diǎn)有點(diǎn)類似C語(yǔ)言中的數(shù)組。關(guān)于向量表(vector)的常用操作過(guò)程:guile (define v (vector 1 2 3 4 5)guile v#(1 2 3 4 5)guile (vector-ref v 0) ; 求第n個(gè)變量的值1guile (vector-length v) ; 求vector的長(zhǎng)度5guile (vector-set! v 2 abc) ; 設(shè)定vector第n個(gè)元素的值guile v#(1 2 abc 4 5)guile (define x (make-vector 5 6) ; 創(chuàng)建向量表guile x#(6 6 6 6 6)make-vector用來(lái)創(chuàng)建一個(gè)向量表,第一個(gè)參數(shù)是數(shù)量,后一個(gè)參數(shù)是添充的值,這和列表中的make-list非常相似。我們可以看出,在Scheme語(yǔ)言中,每種數(shù)據(jù)類型都有一些基本的和它相關(guān)的操作過(guò)程,如字符串,列表等相關(guān)的操作,這些操作過(guò)程都很有規(guī)律,過(guò)程名的單詞之間都用-號(hào)隔開,很容易理解。對(duì)于學(xué)過(guò)C+的朋友來(lái)說(shuō),更類似于某個(gè)對(duì)象的方法,只不過(guò)表現(xiàn)的形式不同了。3. 類型的判斷、比較、運(yùn)算、轉(zhuǎn)換與方法類型判斷Scheme語(yǔ)言中所有判斷都是用類型名加問(wèn)號(hào)再加相應(yīng)的常量或變量構(gòu)成,形如:(類型? 變量)Scheme語(yǔ)言在類型定義中有比較嚴(yán)格的界定,如在C語(yǔ)言等一些語(yǔ)言中數(shù)字0來(lái)代替邏輯類型數(shù)據(jù)False,在Scheme語(yǔ)言中是不允許的。以下為常見(jiàn)的類型判斷和附加說(shuō)明:邏輯型:(boolean? #t) = #t(boolean? #f) = #t 因?yàn)?t和#f都是boolean類型,所以其值為#t(boolean? 2) = #f 因?yàn)?是數(shù)字類型,所以其值為 #f字符型:(char? #space) = #t(char? #newline) = #t 以上兩個(gè)特殊字符:空格和換行(char? #f) = #t 小寫字母 f(char? #;) = #t 分號(hào) ;(char? #5) = #t 字符 5 ,以上這些都是正確的,所以返回值都是 #t(char? 5) = #f 這是數(shù)字 5 ,不是字符類型,所以返回 #f數(shù)字型:(integer? 1) = #t(integer? 2345) = #t(integer? -90) = #t 以上三個(gè)數(shù)均為整數(shù)(integer? 8.9) = #f 8.9不整數(shù)(rational? 22/7) = #t(rational? 2.3) = #t(real? 1.2) = #t(real? 3.14159) = #t(real? -198.34) = #t 以上三個(gè)數(shù)均為實(shí)數(shù)型(real? 23) = #t 因?yàn)檎蛯儆趯?shí)型(number? 5) = #t(number? 2.345) = #t(number? 22/7) = #t其它型:(null? () = #t ; null意為空類型,它表示為 () ,即括號(hào)里什么都沒(méi)有的符號(hào)(null? 5) = #f(define x 123) 定義變量x其值為123(symbol? x) = #f(symbol? x) = #t ; 此時(shí) x 為符號(hào)x,并不表示變量x的值在Scheme語(yǔ)言中如此眾多的類型判斷功能,使得Scheme語(yǔ)言有著非常好的自省功能。即在判斷過(guò)程的參數(shù)是否附合過(guò)程的要求。比較運(yùn)算Scheme語(yǔ)言中可以用,=,= 來(lái)判斷數(shù)字類型值或表達(dá)式的關(guān)系,如判斷變量x是否等于零,它的形式是這樣的:(= x 0) ,如x的值為0則表達(dá)式的值為#t,否則為#f。還有下面的操作:(eqv? 34 34) = #t(= 34 34) = #t以上兩個(gè)form功能相同,說(shuō)明 eqv? 也可以用于數(shù)字的判斷。在Scheme語(yǔ)言中有三種相等的定義,兩個(gè)變量正好是同一個(gè)對(duì)象;兩個(gè)對(duì)象具有相同的值;兩個(gè)對(duì)象具有相同的結(jié)構(gòu)并且結(jié)構(gòu)中的內(nèi)容相同。除了上面提到的符號(hào)判斷過(guò)程和eqv?外,還有eq?和equal?也是判斷是否相等的過(guò)程。eq?,eqv?,equal?eq?,eqv?和equal?是三個(gè)判斷兩個(gè)參數(shù)是否相等的過(guò)程,其中eq?和eqv?的功能基本是相同的,只在不同的Scheme語(yǔ)言中表現(xiàn)不一樣。eq?是判斷兩個(gè)參數(shù)是否指向同一個(gè)對(duì)象,如果是才返回#t;equal?則是判斷兩個(gè)對(duì)象是否具有相同的結(jié)構(gòu)并且結(jié)構(gòu)中的內(nèi)容是否相同,它用eq?來(lái)比較結(jié)構(gòu)中成員的數(shù)量;equal?多用來(lái)判斷點(diǎn)對(duì),列表,向量表,字符串等復(fù)合結(jié)構(gòu)數(shù)據(jù)類型。guile (define v (vector 3 4 5)guile (define w #(3 4 5) ; w和v都是vector類型,具有相同的值#(3 4 5)guile (eq? v w)#f ; 此時(shí)w和v是兩個(gè)對(duì)象guile (equal? v w)#t ; 符合equal?的判斷要求以上操作說(shuō)明了eq? 和equal? 的不同之處,下面的操作更是證明了這一點(diǎn):guile (define x (make-vector 5 6)guile x#(6 6 6 6 6)guile (eq? x x) ; 是同一個(gè)對(duì)象,所以返回#t#tguile (define z (make-vector 5 6)guile z#(6 6 6 6 6)guile (eq? x z) ; 不是同一個(gè)對(duì)象#fguile (equal? x z) ; 結(jié)構(gòu)相同,內(nèi)容相同,所以返回#t#t算術(shù)運(yùn)算Scheme語(yǔ)言中的運(yùn)算符有: + , - , * , / 和 expt (指數(shù)運(yùn)算) 其中 - 和 / 還可以用于單目運(yùn)算,如:(- 4) = -4(/ 4) = 1/4此外還有許多擴(kuò)展的庫(kù)提供了很多有用的過(guò)程,max 求最大 (max 8 89 90 213) = 213min 求最小 (min 3 4 5 6 7) = 3abs 求絕對(duì)值 (abs -7) = 7除了max,min,abs外,還有很多數(shù)學(xué)運(yùn)算過(guò)程,這要根據(jù)你用的Scheme語(yǔ)言的運(yùn)行環(huán)境有關(guān),不過(guò)它們大多是相同的。在R5RS中規(guī)定了很多運(yùn)算過(guò)程,在R5RS的參考資料中可以很容易找到。轉(zhuǎn)換Scheme語(yǔ)言中用符號(hào)組合-來(lái)標(biāo)明類型間的轉(zhuǎn)換(很象C語(yǔ)言中的指針)的過(guò)程,就象用問(wèn)號(hào)來(lái)標(biāo)明類型判斷過(guò)程一樣。下面是一些常見(jiàn)的類型轉(zhuǎn)換過(guò)程:guile (number-string 123) ; 數(shù)字轉(zhuǎn)換為字符串123guile (string-number 456) ; 字符串轉(zhuǎn)換為數(shù)字456guile (char-integer #a) ;字符轉(zhuǎn)換為整型數(shù),小寫字母a的ASCII碼值為9697guile (char-integer #A) ;大寫字母A的值為6565guile (integer-char 97) ;整型數(shù)轉(zhuǎn)換為字符#aguile (string-list hello) ;字符串轉(zhuǎn)換為列表(#h #e #l #l #o) guile (list-string (make-list 4 #a) ; 列表轉(zhuǎn)換為字符串a(chǎn)aaaguile (string-symbol good) ;字符串轉(zhuǎn)換為符號(hào)類型goodguile (symbol-string better) ;符號(hào)類型轉(zhuǎn)換為字符串better五過(guò)程定義過(guò)程(Procedure)在Scheme語(yǔ)言中,過(guò)程相當(dāng)于C語(yǔ)言中的函數(shù),不同的是Scheme語(yǔ)言過(guò)程是一種數(shù)據(jù)類型,這也是為什么Scheme語(yǔ)言將程序和數(shù)據(jù)作為同一對(duì)象處理的原因。如果我們?cè)贕uile提示符下輸入加號(hào)然后回車,會(huì)出現(xiàn)下面的情況:guile +#這告訴我們+是一個(gè)過(guò)程,而且是一個(gè)原始的過(guò)程,即Scheme語(yǔ)言中最基礎(chǔ)的過(guò)程,在GUILE中內(nèi)部已經(jīng)實(shí)現(xiàn)的過(guò)程,這和類型判斷一樣,如 boolean?等,它們都是Scheme語(yǔ)言中最基本的定義。注意:不同的Scheme語(yǔ)言實(shí)現(xiàn)環(huán)境,出現(xiàn)的提示信息可能不盡相同,但意義是一樣的。define不僅可以定義變量,還可以定義過(guò)程,因在Scheme語(yǔ)言中過(guò)程(或函數(shù))都是一種數(shù)據(jù)類型,所以都可以通過(guò)define來(lái)定義。不同的是標(biāo)準(zhǔn)的過(guò)程定義要使用lambda這一關(guān)鍵字來(lái)標(biāo)識(shí)。Lambda關(guān)鍵字Scheme語(yǔ)言中可以用lambda來(lái)定義過(guò)程,其格式如下: (define 過(guò)程名 ( lambda (參數(shù) .) (操作過(guò)程 .)我們可以自定義一個(gè)簡(jiǎn)單的過(guò)程,如下:: (define add5 (lambda (x) (+ x 5) 此過(guò)程需要一個(gè)參數(shù),其功能為返回此參數(shù)加5 的值,如:(add5 11) = 16下面是簡(jiǎn)單的求平方過(guò)程square的定義:(define square (lambda (x) (* x x)與lambda相同的另一種方式在Scheme語(yǔ)言中,也可以不用lambda,而直接用define來(lái)定義過(guò)程,它的格式為: (define (過(guò)程名 參數(shù)) (過(guò)程內(nèi)容 )如下面操作:(define (add6 x) (+ x 6)add6# 說(shuō)明add6是一個(gè)過(guò)程,它有一個(gè)參數(shù)x(add6 23) = 29再看下面的操作:guile (define fun (lambda(proc x y) (proc x y)guile fun#guile (fun * 5 6)30guile (fun / 30 3)10更多的過(guò)程定義上面定義的過(guò)程fun有三個(gè)參數(shù),其中第一個(gè)參數(shù)proc也是一個(gè)操作過(guò)程(因?yàn)樵赟cheme語(yǔ)言中過(guò)程也是一種數(shù)據(jù),可以作為過(guò)程的參數(shù)),另外兩個(gè)參數(shù)是數(shù)值,所以會(huì)出現(xiàn)上面的調(diào)用結(jié)果。guile (define add (lambda (x y) (+ x y)guile add#guile (fun add 100 200)300繼續(xù)上面操作,我們定義一個(gè)過(guò)程add,將add作為參數(shù)傳遞給fun過(guò)程,得出和(fun + 100 200)相同的結(jié)果。guile (lambda (x) (+ x x) 5)10上面的 (lambda(x) (+ x x) 事實(shí)上是簡(jiǎn)單的過(guò)程定義,在后面直接加上操作參數(shù)5,得出結(jié)果10,這樣實(shí)現(xiàn)了匿名過(guò)程,直接用過(guò)程定義來(lái)操作參數(shù),得出運(yùn)算結(jié)果。通過(guò)上面的操作,相信你已初步了解了過(guò)程的用法。既然過(guò)程是一種數(shù)據(jù)類型,所以將過(guò)程作為過(guò)程的參數(shù)是完全可以的。以下過(guò)程為判斷參數(shù)是否為過(guò)程,給出一個(gè)參數(shù),用 procedure? 來(lái)判斷參數(shù)是否為過(guò)程,采用if結(jié)構(gòu)(關(guān)于if結(jié)構(gòu)見(jiàn)下面的介紹):guile (define isp (lambda (x) (if (procedure? x) isaprocedure notaprocedure)guile isp#guile (isp 0)notaprocedureguile (isp +)isaprocedure上面的過(guò)程就體現(xiàn)了Scheme語(yǔ)言的參數(shù)自?。ū鎰e)能力,0是數(shù)字型,所以返回notaprocedure;而+是一個(gè)最基礎(chǔ)的操作過(guò)程,所以返回isaprocedure。過(guò)程的嵌套定義在Scheme語(yǔ)言中,過(guò)程定義也可以嵌套,一般情況下,過(guò)程的內(nèi)部過(guò)程定義只有在過(guò)程內(nèi)部才有效,相當(dāng)C語(yǔ)言中的局部變量。如下面的代碼的最終結(jié)果是50:(define fix (lambda (x y z) (define add (lambda (a b) (+ a b) (- x (add y z)(display (fix 100 20 30)此時(shí)過(guò)程add只在fix過(guò)程內(nèi)部起做用,這事實(shí)上涉及了過(guò)程和變量的綁定,可以參考下面的關(guān)于過(guò)程綁定(let,let* 和letrec)的介紹。過(guò)程是初學(xué)者難理解的一個(gè)關(guān)鍵,隨著過(guò)程參數(shù)的增加和功能的增強(qiáng),過(guò)程的內(nèi)容變得越來(lái)越復(fù)雜,小括號(hào)也會(huì)更多,如果不寫出清晰的代碼的話,讀代碼也會(huì)成為一個(gè)難題。熟悉了 scheme 基本概念、數(shù)據(jù)類型和過(guò)程(函數(shù))后, 下一部分我們來(lái)學(xué)習(xí) scheme 的結(jié)構(gòu)、遞歸調(diào)用和其他擴(kuò)展功能。六常用結(jié)構(gòu)順序結(jié)構(gòu)也可以說(shuō)成由多個(gè)form組成的form,用begin來(lái)將多個(gè)form放在一對(duì)小括號(hào)內(nèi),最終形成一個(gè)form。格式為:(begin form1 form2 )如用Scheme語(yǔ)言寫成的經(jīng)典的helloworld程序是如下樣子的:(begin (display Hello world!) ; 輸出Hello world! (newline) ; 換行if結(jié)構(gòu)Scheme語(yǔ)言的if結(jié)構(gòu)有兩種格式,一種格式為:(if 測(cè)試 過(guò)程1 過(guò)程2),即測(cè)試條件成立則執(zhí)行過(guò)程1,否則執(zhí)行過(guò)程2。例如下面代碼:(if (= x 0) (display is zero)(display not zero)還有另一種格式:(if 測(cè)試 過(guò)程) ,即測(cè)試條件成立則執(zhí)行過(guò)程。例如下面代碼:(if ( (define w (lambda (x) (cond ( x 0) upper) (else equal)guile w#guile (w 9)upperguile (w -8)lowerguile (w 0)equal上面程序代碼中,我們定義了過(guò)程w,它有一個(gè)參數(shù)x,如果x的值大于0,則返回符號(hào)upper,如x的值小于0則返回符號(hào)lower,如x 的值為0則返回符號(hào)equal。下載已做成可執(zhí)行腳本的 例程。cond可以用if形式來(lái)寫,上面的過(guò)程可以如下定義:guile (define ff (lambda (x) (if ( x 0) upper zero)guile ff#guile (ff 9)upperguile (ff -9)lowerguile (ff 0)zero這在功能上是和cond一樣的,可以看出cond實(shí)際上是實(shí)現(xiàn)了if的一種多重嵌套。case結(jié)構(gòu)case結(jié)構(gòu)和cond結(jié)構(gòu)有點(diǎn)類似,它的格式為:(case (表達(dá)式) (值) 操作) . (else 操作)case結(jié)構(gòu)中的值可以是復(fù)合類型數(shù)據(jù),如列表,向量表等,只要列表中含有表達(dá)式的這個(gè)結(jié)果,則進(jìn)行相應(yīng)的操作,如下面的代碼:(case (* 2 3) (2 3 5 7) prime) (1 4 6 8 9) composite)上面的例子返回結(jié)果是composite,因?yàn)榱斜?1 4 6 8 9)中含有表達(dá)式(* 2 3)的結(jié)果6;下面是在Guile中定義的func過(guò)程,用到了case結(jié)構(gòu):guile (define func (lambda (x y) (case (* x y) (0) zero) (else nozero)guile func#guile (func 2 3)nozeroguile (func 2 0)zeroguile (func 0 9)zeroguile (func 2 9)nozero可以下載另一個(gè)腳本文件 te.scm,參考一下。and結(jié)構(gòu)and結(jié)構(gòu)與邏輯與運(yùn)算操作類似,and后可以有多個(gè)參數(shù),只有它后面的參數(shù)的表達(dá)式的值都為#t時(shí),它的返回值才為#t,否則為#f??聪旅娴牟僮鳎篻uile (and (boolean? #f) ( (and (boolean? 2) ( (and (boolean? 2) ( 8 12)#f如果表達(dá)式的值都不是boolean型的話,返回最后一個(gè)表達(dá)式的值,如下面的操作:guile (and (list 1 2 3) (vector a b c)#(a b c)guile (and 1 2 3 4 )4guile (and e d c b a)aor結(jié)構(gòu)or結(jié)構(gòu)與邏輯或運(yùn)算操作類似,or后可以有多個(gè)參數(shù),只要其中有一個(gè)參數(shù)的表達(dá)式值為#t,其結(jié)果就為#t,只有全為#f時(shí)其結(jié)果才為#f。如下面的操作:guile (or #f #t)#tguile (or #f #f)#fguile (or (rational? 22/7) ( (rational? 22/7)#tguile (real? 22/7)#tguile (or (real? 4+5i) (integer? 3.22)#f我們還可以用and和or結(jié)構(gòu)來(lái)實(shí)現(xiàn)較復(fù)雜的判斷表達(dá)式,如在C語(yǔ)言中的表達(dá)式:(x 100) & (y 100) | (y 100)在Scheme中可以表示為:guile (define x 123)guile (define y 80)guile (and ( x 100) ( (or ( x 100) ( y 100)#tScheme語(yǔ)言中只有if結(jié)構(gòu)是系統(tǒng)原始提供的,其它的cond,case,and,or,另外還有do,when,unless等都是可以用宏定義的方式來(lái)定義的,這一點(diǎn)充分體現(xiàn)了Scheme的元語(yǔ)言特性,關(guān)于do,when等結(jié)構(gòu)的使用可以參考R5RS。七遞歸調(diào)用用遞歸實(shí)現(xiàn)階乘在Scheme語(yǔ)言中,遞歸是一個(gè)非常重要的概念,可以編寫簡(jiǎn)單的代碼很輕松的實(shí)現(xiàn)遞歸調(diào)用,如下面的階乘過(guò)程定義:(define factoral (lambda (x) (if ( (define factoral (lambda (x) (if ( factoral#guile (factoral 4)24另一種遞歸方式下面是一另一種遞歸方式的定義:(define (factoral n) (define (iter product counter) (if ( counter n) product (iter (* counter product) (+ counter 1) System Message: WARNING/2 (, line 954)Definition list ends without a blank line; unexpected unindent.(iter 1 1)System Message: WARNING/2 (, line 955)Definition list ends without a blank line; unexpected unindent.(display (factoral 4)這個(gè)定義的功能和上面的完全相同,只是實(shí)現(xiàn)的方法不一樣了,我們?cè)谶^(guò)程內(nèi)部實(shí)現(xiàn)了一個(gè)過(guò)程iter,它用counter參數(shù)來(lái)計(jì)數(shù),調(diào)用時(shí)從1開始累計(jì),這樣它的展開過(guò)程正好和我們上面的遞歸過(guò)程的從4到1相反,而是從1到4。循環(huán)的實(shí)現(xiàn)在Scheme語(yǔ)言中沒(méi)有循環(huán)結(jié)構(gòu),不過(guò)循環(huán)結(jié)構(gòu)可以用遞歸來(lái)很輕松的實(shí)現(xiàn)(在Scheme語(yǔ)言中只有通過(guò)遞歸才能實(shí)現(xiàn)循環(huán))。對(duì)于用慣了C語(yǔ)言循環(huán)的朋友,在Scheme中可以用遞歸簡(jiǎn)單實(shí)現(xiàn):guile (define loop (lambda(x y) (if ( loop#guile (loop 1 10)1 2 3 4 5 6 7 8 9 10這只是一種簡(jiǎn)單的循環(huán)定義,過(guò)程有兩個(gè)參數(shù),第一個(gè)參數(shù)是循環(huán)的初始值,第二個(gè)參數(shù)是循環(huán)終止值,每次增加1。相信讀者朋友一定會(huì)寫出更漂亮更實(shí)用的循環(huán)操作來(lái)的。八變量和過(guò)程的綁定let,let*,letrec在多數(shù)編程語(yǔ)言中都有關(guān)于變量的存在的時(shí)限問(wèn)題,Scheme語(yǔ)言中用let,let*和letrec來(lái)確定變量的存在的時(shí)限問(wèn)題,即局部變量和全局變量,一般情況下,全局變量都用define來(lái)定義,并放在過(guò)程代碼的外部;而局部變量則用let等綁定到過(guò)程內(nèi)部使用。用let可以將變量或過(guò)程綁定在過(guò)程的內(nèi)部,即實(shí)現(xiàn)局部變量:guile let#從上面的操作可以看出let是一個(gè)原始的宏,即guile內(nèi)部已經(jīng)實(shí)現(xiàn)的宏定義。下面的代碼顯示了let的用法(注意多了一層括號(hào)):guile (let (x 2) (y 5) (* x y)10它的格式是:(let () ),下面是稍復(fù)雜的用法:guile (let (x 5) (define foo (lambda (y) (bar x y) (define bar (lambda (a b) (+ (* a b) a) (foo (+ x 3)45以上是Guile中的代碼實(shí)現(xiàn)情況。它的實(shí)現(xiàn)過(guò)程大致是:(foo 8) 展開后形成 (bar 5 8),再展開后形成 (+ (* 5 8) 5) ,最后其值為45。再看下面的操作:guile (let (isze
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國(guó)高速?zèng)_床片行業(yè)市場(chǎng)全景評(píng)估及投資前景展望報(bào)告
- 中國(guó)服裝及衣著附件行業(yè)市場(chǎng)運(yùn)營(yíng)趨勢(shì)分析及投資潛力研究報(bào)告
- 2025年中國(guó)電鋼琴行業(yè)發(fā)展監(jiān)測(cè)及市場(chǎng)發(fā)展?jié)摿︻A(yù)測(cè)報(bào)告
- 茶葉項(xiàng)目可行性研究報(bào)告模板可編輯
- 《安全驗(yàn)收評(píng)價(jià)報(bào)告》編寫提綱
- 2025年中國(guó)新的充氣橡膠輪胎行業(yè)全景評(píng)估及投資規(guī)劃建議究報(bào)告
- 托肩架項(xiàng)目可行性分析報(bào)告(模板參考范文)
- 2025年中國(guó)南美白對(duì)蝦行業(yè)市場(chǎng)運(yùn)行態(tài)勢(shì)及投資戰(zhàn)略咨詢研究報(bào)告
- 如何做好節(jié)假日期間的安全生產(chǎn)工作
- 教育心理學(xué)的目標(biāo)定向理論在學(xué)習(xí)中的應(yīng)用研究
- 快消品行業(yè)市場(chǎng)調(diào)研與銷售策略制定
- 2024年度小紅書商業(yè)MCN機(jī)構(gòu)經(jīng)營(yíng)洞察報(bào)告
- 建材勞動(dòng)合同范例
- 中國(guó)嬰幼兒 科學(xué)配餐與食品制作指導(dǎo)手冊(cè)
- 《生鮮培訓(xùn)手冊(cè)》課件
- 五年級(jí)上冊(cè)語(yǔ)文必背內(nèi)容+默寫表
- 初一生活學(xué)習(xí)指導(dǎo)
- 2024至2030年中國(guó)臭氧濃度分析儀數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 《化工單元操作》教案
- 2024年露營(yíng)帳篷項(xiàng)目可行性研究報(bào)告
- 《公務(wù)員錄用體檢操作手冊(cè)(試行)》
評(píng)論
0/150
提交評(píng)論