日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scheme 编程语言(1)介绍

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scheme 编程语言(1)介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Scheme 編程語言(1)

Translator: Once Day date:2022年10月22日

漫漫長路有人對你微笑過嗎…

僅供學習交流之用,請尊重原書版權

原書:《The Scheme Programming Language, Fourth Edition》R. Kent Dybvig.

原書章節: The Scheme Programming Language : Chapter 1.Introduction.

這是一個學習的過程,不斷修改和完善,供自己日后復習,水平有限,自娛自樂。

機翻文檔,兼帶修改。私人筆記,切莫多言

1.介紹

Scheme是一種通用的計算機編程語言。它是一種高級語言,支持操作結構化數據,如字符串、列表和向量,以及傳統的數據類型(數字和字符)。Scheme通常被認為專于符號處理程序,但它同樣具有豐富的數據類型和靈活的控制結構,因此也可作為通用的語言??梢允褂肧cheme來編寫文本編輯器、優化的編譯器、操作系統、圖形軟件包、專家系統、數值應用程序、財務分析軟件包、虛擬現實系統,以及幾乎所有其他類型的應用程序。Scheme是一種相當簡單的語言,因為它基于少量的語法形式和語義概念。大多數的Scheme實現具有交互式的shell,因此可以一邊交互一邊學習。然而,Scheme是一種很難完全理解的語言,想要完全學會這門語言,需要細心且認真的學習和實踐

對于相同的實現,Scheme程序在不同機器上的各版本之間是高度可移植的,因為對程序員來說,機器依賴關系幾乎是完全隱藏的。經過很多Scheme語言設計者的努力,它們還可以在不同的實現之間移植。這些Scheme語言設計者發布了一系列關于Scheme的報告,即“修訂版報告”。最近的“修訂(6)報告”強調通過一組標準庫和定義新的可移植庫及頂級程序的標準機制來實現可移植性。

一些早期的Scheme系統效率低下且速度緩慢,不過許多基于編譯器的新Scheme實現速度很快,其程序運行速度與用低級語言編寫的等效程序一樣快。有時會保留一些相對低效的功能,如支持泛型算法的實時檢查(run-time checks),以及幫助程序員檢測和糾正各種常見的編程錯誤。這些檢查功能可能在許多實現中被禁用。

Scheme支持多種類型的數據值或對象,包括字符、字符串、符號、對象的列表或向量,以及一整套數值數據類型,包括復數、實數和任意精度有理數。

保存對象內容所需的存儲空間根據情況動態分配,并保留存儲空間直到不再需要,然后自動釋放,這通常由垃圾收集器來定期釋放不可訪問對象所使用的存儲空間。簡單的原子值,例如小整數、字符、布爾值和空列表,通常表示為直接值(不需要通過指針來間接訪問存儲空間),因此不會產生分配或回收開銷。

無論如何表示,所有對象都是一級數據(first-class data)值。因為它們是無限保留的,所以它們可以作為過程(函數)的參數自由傳遞,作為過程(函數)的值返回,并組合成新的對象。這與許多其他的編程語言不同,在這些語言中,數組等復合數據有以下情況:

  • 要么是靜態分配且永不釋放
  • 要么是在進入代碼塊時分配,在代碼塊退出時無條件釋放
  • 要么是由程序員顯式分配并釋放

Scheme語言的核心是一個語法形式的小核心,所有其他形式都是從它構建的。這些核心形式,以及從它們派生出的一組擴展語法形式和一組基本過程組成了完整的Scheme語言。Scheme的解釋器或編譯器可以非常小,可能非常快,而且非??煽?。擴展的語法形式和許多基本過程可以用Scheme自定義,從而簡化了實現并提高了可靠性。

Scheme程序與Scheme數據結構共享一個公共的打印表示。因此,任何Scheme程序都具有作為Scheme對象的原生內部表示。例如,變量和語法關鍵字對應符號,而結構化語法形式對應列表(lists)。這種表示是Scheme提供的語法擴展工具的基礎,該工具用于根據現有的語法形式和過程定義新的語法形式。它還促進了在Scheme中直接實現解釋器、編譯器和其他針對Scheme的程序轉換工具,以及在Scheme中實現針對其他編程語言的程序轉換工具。

Scheme變量和關鍵字具有詞法范圍(lexically scoped),Scheme程序具有塊結構。標識符可以導入到程序或庫中,也可以在給定的代碼塊(如庫、程序或過程體)中本地綁定。局部綁定僅在其詞法范圍內可見,即在組成特定代碼塊的程序文本內。如果在此塊之外出現同名標識符,則指向不同的綁定,如果塊外部沒有對標識符的綁定,則引用無效。塊可以嵌套,一個塊中的綁定可以遮蔽周圍塊中同名標識符的綁定。綁定的范圍是綁定標識符可見的塊減去標識符被遮蔽的塊剩下的其他部分。塊結構和詞匯作用域有助于創建模塊化、易于閱讀、易于維護和可靠的程序。高效的詞法作用域代碼是可能的,因為編譯器可以在程序求值之前確定所有(標識符)綁定的作用域以及每個標識符引用解析對應的綁定。當然,這并不意味著編譯器可以確定所有變量的值,因為在大多數情況下,直到程序執行時才計算出實際的值。

在大多數語言中,過程(函數)定義只是名稱與代碼塊的關聯。代碼塊的某些局部變量是過程(函數)的參數。在某些語言中,過程定義可以出現在另一個代碼塊或過程中,但該過程只能在定義的代碼塊中被調用。在其他情況下,過程只能在頂層區域中定義。在Scheme中,過程定義可能出現在另一個塊或過程中,并且該過程可能在此后的任何時候被調用,即使所包含的塊已經完成了它的執行。為了支持詞法作用域,過程在其代碼中附帶詞法上下文(環境)。

此外,Scheme過程并不總是被命名。相反,過程是第一類數據對象,就像字符串或數字,并且變量綁定到過程與綁定到其他對象的方式相同。

與大多數其他編程語言中的過程一樣,Scheme過程可以是遞歸的。也就是說,任何過程都可以直接或間接地調用自己。許多算法都是通過使用遞歸形式來最優雅或最有效地表達出來。遞歸的一種特殊情況稱為尾部遞歸,用于表示迭代或循環。尾部調用發生在一個過程直接返回另一個過程調用的結果時。當過程直接或間接遞歸地尾部調用自身時,就會發生尾部遞歸。Scheme實例需要將尾部調用實現為跳轉(goto),因此可以避免與遞歸相關的存儲開銷。所以,Scheme程序員只需要掌握簡單的過程調用和遞歸,而不需要關心常見循環構造的分類。

Scheme支持定義帶有continuations(延續流)的任意控制結構。continuation是一種過程,它將程序的剩余部分體現在程序的給定點上。continuation可以在程序執行期間的任何時候獲得。與其他過程一樣,continuation是一級對象,可以在創建后的任何時間調用。無論何時調用它,程序都立即從獲得continuation的(代碼)點開始繼續。延續允許實現復雜的控制機制,包括顯式回溯、多線程和協程。

Scheme還允許程序員通過編寫轉換過程( transformation procedures)來定義新的語法形式(syntactic forms)或語法擴展(syntactic extensions),轉換過程確定每個新的語法形式如何映射到現有的語法形式。在便利的高級模板語言的幫助下,這些轉換過程本身在Scheme中表示,并且該高級模板語言自動化完成語法檢查、輸入解構和輸出重構。默認情況下,在轉換過程中維護詞法作用域,但是程序員可以控制轉換輸出中出現的所有標識符的作用域。語法擴展用處很大,如定義新的語言結構、模擬在其他語言中發現的語言結構、實現內聯代碼擴展的效果,以及甚至在Scheme中模擬整個語言。大多數大型Scheme程序都是由混合的語法擴展和過程定義構建的。

Scheme從Lisp語言演變而來,被認為是Lisp的一種方言。Scheme從Lisp繼承了很多特性,包括以下部分:

  • 將值作為第一級對象的處理
  • 一些重要的數據類型(包括符號和列表)
  • 將程序表示為對象

詞法作用域和塊結構是來自Algol 60的特性。Scheme是第一個采用詞法作用域和塊結構、一級過程、將尾部調用作為跳轉、延續和詞法作用域語法擴展等特性的Lisp方言。

Common Lisp和Scheme都是當代的Lisp語言,它們各自的發展都受到了對方的影響。與Scheme類似,但與早期的Lisp語言不同的是,Common Lisp采用了詞匯作用域和一級過程,盡管Common Lisp的語法擴展功能不考慮詞匯作用域。但是,Common Lisp的過程求值規則不同于其他對象的求值規則,它為過程變量維護了單獨的名稱空間,因此無法將過程用作第一級對象。此外,Common Lisp不支持延續,也不要求對尾部調用進行適當的處理,但它支持Scheme中未包含的幾個不太通用的控制結構。雖然這兩種語言是相似的,但是Common Lisp包含了更多專門的構造,而Scheme則包含了更多通用的構建塊,可以在此基礎上構建這些Common Lisp獨有的構造(和其他構造)。

本章的其余部分將描述Scheme的語法和命名約定以及本書中使用的排版約定。

1.1 Scheme 語法

Scheme程序由關鍵字、變量、結構化形式、常量數據(數字、字符、字符串、引用向量、引用列表、引用符號等)、空格和注釋組成。

關鍵字、變量和符號統稱為標識符。標識符可以由字母、數字和某些特殊字符組成,特殊字符包括以下部分:

?, !, ., +, -, *, /, <, =, >, :, $, %, ^, &, _, ~, @

除此之外,特殊字符還含有一組額外的Unicode字符。標識符不能以@符號開頭,通常也不能以任何可組成有效數字的字符開頭,例如,數字、加號(+)、負號(-)或小數點(.),像+, -, .如果用來表示正數,負數以及小數,那么是無效的標識符。

但是單純表示+,-,.那么它們就是有效的標識符,如+kl,->等都是有效的,只要不組成一個有效數字即可。

例如,hi, Hello, n,x, x3, x+2和?$&*!!都是標識符。

標識符由空格、注釋、圓括號()、方括號[]、(雙)引號(")和散列標記(#)分隔。分隔符或任何其他Unicode字符可以作為\xsv;形式的轉義符,并可位于在標識符名稱中的任何位置,其中sv是十六進制表示的字符標量值。

Scheme標識符的長度沒有固有的限制,程序員可以根據需要使用盡可能多的字符。但是,長標識符不能代替注釋,頻繁使用長標識符會使程序難以格式化,從而導致難以閱讀。一個好的規則是,當標識符的范圍很小時使用短標識符,當標識符的范圍較大時使用長標識符。

標識符可以用大寫字母和小寫字母的任意組合書寫,并且區分大小寫。例如, abcde, Abcde, AbCdE和ABCDE都引用不同的標識符。這與以前版本的修正報告(Revised Report)有所不同。

結構化形式(Structured forms和列表常量被括在圓括號內,例如(a b c)或(* (- x 2) y)??樟斜肀粚憺?)。匹配的方括號([])可以用來代替圓括號,通常用于分隔某些標準語法形式的子表達式,以提高可讀性,如本書中的示例所示。向量的書寫方式與列表類似,只是它們的前面是#,然后是( ),例如,#(這是一個符號向量)。字節向量被寫成由#vu8()括起來的無符號字節值序列(0到255的精確整數),例如,#vu8(3 250 45 73)。

字符串用雙引號括起來,例如,"I am a string"。字符前面是#\,例如#\a表示字符a。字符和字符串常量區分大小寫,就像在標識符中一樣。數字可以寫成整數,例如-123,也可以寫成分數,例如1/2。小數可以用浮點數或科學記數法表示,例如1.3或1e23。還可以寫成復數,使用直角坐標或極坐標來表示,例如1.3 - 2.7i或-1.2@73。在數字的表示中,可忽略大小寫的區別。

表示true和false的布爾值寫為#t和#f。Scheme條件表達式實際上將#f視為false,而將所有其他對象視為true,因此3、0、()、“false”和nil都計算為true。

關于每種常量數據類型的語法的詳細信息在第6章的各個章節和從第455頁開始的Scheme的正式語法中給出。

  • Operations on Objects (scheme.com)(原文第六章)
  • Formal Syntax (scheme.com)(原文455頁)

Scheme表達式可能跨越幾行,不需要顯式輸入終止符。表達式之間的空白字符(空格和換行符)的數量并不重要,所以Scheme程序(代碼)應該縮進以使得代碼盡可能易讀地顯示代碼的結構。注釋可以出現在Scheme程序的任何一行,以分號(;)開始,直到該行的結束(換行符截止)。解釋特定Scheme表達式的注釋通常以同等縮進級別放置于表達式的上一行。解釋一個過程或一組過程的注釋通常放在過程之前,沒有縮進。通常使用多個注釋字符來分隔后一種注釋,例如;;; 解釋以下過程做了什么....

支持另外兩種形式的注釋: 塊注釋和數據注釋。塊注釋由#|和|#對分隔,并且可以嵌套。數據注釋由#;前綴及其后面的數據(printed data value)組成。數據注釋通常用于注釋掉單個定義或表達式。例如,(three #;(not four) element list)注釋掉了(not four)。數據注釋也可以嵌套,比如#;#;(a)(b)有注釋掉(a)和(b)的不太明顯的效果。

一些Scheme值,例如過程(procedures)和端口(ports),沒有標準的打印表示,因此永遠不能作為常量出現在程序的打印語法中。本書使用了#<description>來顯示一個過程的輸出,例如#<procedure>或#<port>。

1.2 Scheme 命名約定

Scheme的命名約定旨在提供高度的規律性。以下是這些命名約定的列表:

  • 謂詞名稱以問號結尾(?)。謂詞是返回true或false答案的過程,如eq?, 0 ?,和字符串= ?。常見的數值比較=,<, >, <=和>=是這種命名約定的例外,可以不用加?。
  • 類型謂詞,例如pair?,從類型的名稱(在本例中是pair)和問號創建。
  • 大多數用于字符、字符串和向量的過程其名稱都以前綴char-、string-和vector-開頭,例如string-append。(一些列表過程的名稱以list-開頭,但大多數情況下沒有以該前綴開頭。)
  • 將一種類型對象轉換為另一種類型對象的過程其名稱寫為type1->type2,例如vector->list。
  • 具有副作用的過程和語法形式其名稱以感嘆號(!)結尾,這包括set!和vector-set!。技術上執行輸入或輸出的過程會產生副作用,但它們是此規則的例外,因此不用加上!。

程序員應該盡可能在自己的代碼中使用這些相同的約定。

1.3 排版和符號約定

有一類標準過程或語法形式被稱為返回未指定值(return unspecified),因為它們唯一目的是產生某種副作用。這意味著Scheme實現可以自由返回任意數量的值,其每個值都可以是任何Scheme對象,以此作為過程或語法形式的值。不要指望這些值在不同Scheme實現,或者在相同Scheme實現的不同版本,亦或是在過程或語法形式的兩種使用等之間是相同的。一些Scheme系統通常使用特殊對象來表示未指定的值。交互式Scheme系統通常會禁止此對象的打印,因此對于返回未指定值的表達式,不打印它們的值。

雖然大多數標準過程返回一個值,但該語言支持通過第5.8節描述的機制返回0、1、多個甚至可變數量值的過程。如果一個子表達式求值為多個值,那么某些標準表達式可以求值為多個值,例如,通過調用返回多個值的過程。當出現這種情況時,我們說表達式返回的是“值”,而不是其子表達式的“值”。類似地,如果一個標準過程從其過程實參(procedure argument, 參數是一個過程)調用中返回值,則稱為返回其過程實參返回的值。

本書使用“must”和“should”來描述程序需求,例如在調用vector-ref時,需要提供一個小于vector長度的索引。如果使用了“必須”這個詞,這意味著需求是由Scheme實現強制執行的,即拋出異常,通常帶有條件類型和斷言。如果使用了“should”,則可能引發異常,也可能不引發異常,如果沒有,則程序的行為未定義。

短語“語法違規(syntax violation)”用于描述程序格式不正確的情況。在程序執行之前可以檢測到語法違規。當檢測到語法違規時,將引發類型和語法的異常,程序將不執行。

本書中使用的排版慣例很簡單。所有Scheme對象都使用打字機字體打印,就像在鍵盤上鍵入一樣。這包括語法關鍵字、變量、常量對象、Scheme表達式和示例程序。斜體用于在語法形式的描述中分隔語法變量和在過程的描述中分隔參數。斜體字也用在技術術語第一次出現時將其分隔開來。一般來說,語法形式和過程的名稱從來不大寫,即使在句子的開頭也是如此。對于用斜體字書寫的語法變量也是如此(開頭不大寫)。

在對語法形式或過程的描述中,一個或多個原型模板表明了在使用該過程的應用程序中語法形式或參數的正確數量。關鍵字或過程名用打字機字體給出,括號也是。語法或參數的其余部分以斜體顯示,使用的名稱暗示了語法形式或過程所期望的表達式或參數的類型。省略號用于指定子表達式或參數出現0次或多次。例如,(or expr …)描述or語法形式,它有零個或多個子表達式,(member obj list)描述一個成員過程,它需要兩個參數,一個對象和一個列表。

如果語法形式的結構與它的原型不匹配,就會發生語法沖突。類似地,如果傳遞給標準過程的參數數量與指定接收的參數數量不匹配,則會引發帶有條件類型和斷言的異常。如果標準過程接收到的實參的類型不是其名稱所隱含的類型,或者不滿足過程描述中給出的其他條件,則會引發帶有條件類型和斷言的異常。例如,vector-set!原型是

(vector-set! vector n obj)

描述說明n必須是一個精確的非負整數,并嚴格小于向量的長度。因此,vector-set!必須接收三個參數,第一個參數必須是一個向量,第二個參數必須是一個小于向量長度的精確非負整數,第三個參數可以是任何Scheme值。否則,將引發帶有條件類型和斷言的異常。

在大多數情況下,所需的實參類型是顯而易見的,例如vector、obj或binary-input-port。在其他情況下,主要是在數字例程的描述中使用縮寫,例如int表示整數,exint表示精確整數,fx表示固定數值。對于那些受影響的部分,在對應章節的開始部分會解釋這些縮寫。

(第一章完,后續章節將會慢慢更新…)

總結

以上是生活随笔為你收集整理的Scheme 编程语言(1)介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。