热门问题
时间线
聊天
视角
讀取-求值-輸出迴圈
来自维基百科,自由的百科全书
Remove ads
「讀取-求值-輸出」迴圈(英語:Read-Eval-Print Loop,簡稱REPL),也被稱做互動式頂層構件(英語:interactive toplevel),是一個簡單的,互動式的編程環境。這個詞常常用於指代一個Lisp的互動式開發環境,也能指代命令列的模式。
![]() | 此條目包含過多行話或專業術語,可能需要簡化或提出進一步解釋。 (2018年4月20日) |
此條目沒有列出任何參考或來源。 (2018年4月20日) |
概述
「讀入-求值-輸出」迴圈 的名字來自於以下幾個Lisp用來實作這種機制的內建函式:
- 讀入函式(read)接收一個來自於使用者的表達式,將其解析成資料結構並存入記憶體。例如,使用者可能會輸入一個s-表達式
(+ 1 2 3)
,這句話會被解析成一個包含四個元素的鏈結串列。 - 求值函式(eval)負責處理內部的資料結構並對其求值。在Lisp中,求一個以函式名開頭的s-表達式意味著對接下來的參數呼叫那個函式。所以函式"
+
"被在參數1 2 3
上呼叫,產生結果6
。 - 輸出函式(print)接受求值結果,並將其呈現給使用者。儘管當前的結果「
6
」並不具有複雜的格式,但如果是一個較為複雜的表達式,那麼它將會被精心處理,以便於更方便地被理解。
REPL使得探索性的編程和除錯更加便捷,因為「讀取-求值-輸出」迴圈通常會比經典的「編輯-編譯-執行-除錯」模式要更快。
優點
REPL對於學習一門新的程式語言具有很大的幫助,因為它能立刻對初學者做出回應。許多工具集和程式語言使用REPL研究演算法、進行除錯,比如MATLAB,ROOT(頁面存檔備份,存於網際網路檔案館),SciPy和IPython。Python的doctest模組能夠通過捕捉自身REPL命令列的輸出使測試代碼更容易地進行。
由於 print
函式輸出的資料格式(字串)與使用者輸入的資料格式(字串)相同,大多數輸出的結果也可以被帶回到 read
函式作為輸入。然而,有的時候輸出的結果只能代表求值結果而不是求值結果本身,比如一個socket控制代碼或一些類別的實例。比如在Python中使用 <__模块名__.类名 实例名>
這種形式來代表一個實例本身,在Common Lisp當中就使用 #<whatever>
的形式。而在CLIM,SLIME以及Symbolics Lisp Machine的REPL卻有辦法讀取很難被完全字串化的這些對象。他們記錄被輸出過的對象,之後當代碼被讀取時,這些對象能夠被解析並重新被使用。
Remove ads
實作
為了實作一個 Lisp REPL,只需要實作這三個函式和一個不停輪詢的函式即可(當然,求值函式的實作是最為複雜的,因為它在內部要實作像 car
與 +
的原始函式以及像if
一樣的特殊運算子)。這些工作完成了之後,一個基本的REPL就可以用如下的簡單形式表達:(loop (print (eval (read))))
。
一種實作eval
的方式就是實作一個遞迴處理抽象語法樹(該語法樹被 read
函式建立)的函式。另一種可行的方法是將這個抽象語法樹編譯為機器碼並執行。
主要的REPL程式語言環境
APL、BASIC、Clojure、F#、Haskell、J、Julia、Perl、PHP、Prolog、Python、R、Ruby、Scala、Smalltalk、Standard ML、Swift、Tcl、Javascript、Java(自JDK 9起)
外部連結
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads