使用 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 可以通过明确的范围规则实现模块化、递归和顺序编程。