使用 let 這個名稱是因為它反映了引入臨時綁定的數學起源,如 “Let ( x = 2 ) and ( y = 3 )”

Scheme 中的let 語句是一個綁定構造,用來定義本地範圍內的變數。它允許您為變數建立臨時綁定,然後使用這些綁定執行程式碼區塊。這對於保持程式碼模組化和避免全域變數污染特別有用。

在Scheme中let主要有3種形式:

  • let:用於建立簡單本地綁定的標準let。
  • let*:順序let,其中綁定可以依賴先前綁定的結果。
  • 命名letlet 的特殊形式,用於建立遞歸循環或命名過程。

在最簡單的形式中,let 建立局部變數綁定並使用這些綁定計算表達式。

(let ((variable1 value1)
      (variable2 value2))
  expression)
  • 綁定:對的列表,其中每對將 value 分配給 variable
  • 表達式let 的主體,可以使用本地定義的變數。

範例

(let ((x 10)
      (y 20))
  (+ x y))
  • 這定義了兩個局部變數:x (10) 和y (20)。
  • 然後使用這些變數計算(+ x y)

結果30


let* 構造

let* 構造與let 類似,但綁定是按順序進行評估的。這意味著後面的綁定可以依賴前面的綁定。

(let* ((variable1 value1)
       (variable2 expression-using-variable1))
  expression)

範例

(let* ((x 10)
       (y (+ x 5)))
  (* x y))
  • 第一個綁定將10 分配給x
  • 第二個綁定使用x 的值將y 計算為(+ x 5)
  • 主體計算(* x y)

結果150


命名為let

命名的 letlet 的特殊形式,它為 let 區塊本身提供名稱,將其轉換為遞歸過程。這對於創建循環或遞歸計算很有用。

(let name ((variable1 initial-value1)
           (variable2 initial-value2))
  body-expression)
  • 名称let 块被赋予一个名称,有效地定义一个函数。
  • 綁定:變數的初始值,類似於標準let
  • Body:表達式可以遞歸呼叫命名的let

範例:使用名為 let 進行循環

(let loop ((n 5)
           (result 1))
  (if (= n 0)
      result
      (loop (- n 1) (* result n))))
  • loop 函數以n = 5result = 1 開頭。
  • 如果n0,則回傳result
  • 否則,它使用 n - 1result * n 遞歸呼叫自身。

結果120(5 的階乘)


總結表

建設描述使用案例
let定義變數的本地綁定。當所有綁定都是獨立且不相互依賴時使用。
let*定義順序本地綁定。當後面的綁定依賴前面的綁定的結果時使用。
命名為let定義遞歸本機程序。在本地上下文中使用 for 迴圈、迭代計算或遞歸。

範例

使用let進行本地計算

(let ((x 2)
      (y 3))
  (+ (* x x) (* y y)))

結果13(計算x² + y²


使用 let* 進行順序依賴

(let* ((x 2)
       (y (* x x))
       (z (* y x)))
  z)

結果8(計算


使用命名let進行遞歸計算

(let factorial ((n 5)
                (result 1))
  (if (= n 0)
      result
      (factorial (- n 1) (* result n))))

結果120(5 的階乘)


透過使用 letlet* 和命名 let,Scheme 可以透過明確的範圍規則實現模組化、遞歸和順序程式設計。