Scheme的let语句

11
在函数式编程语言Scheme中,没有赋值语句。但是在let语句中。
(let ((x 2))
    (+ x 3))
你正在给x分配2,那么为什么这不违反函数式编程中没有赋值语句的原则?
2个回答

16

“Scheme是一种函数式编程语言”的说法是不正确的。在Scheme中,鼓励采用函数式编程风格,但并非强制要求。事实上,您可以使用 set!(赋值语句!)来修改任何变量的值:

(define x 10)
(set! x (+ x 3))
x
=> 13

关于这个问题中的 let 语句,记住这样一个表达式:

(let ((x 10))
  (+ x 3))
=> 13

......这只是语法糖,实际上在底层的实现是这样的:

((lambda (x)
   (+ x 3))
 10)
=> 13

注意,let 对其变量执行一次性的 单赋值,因此本质上不违反任何纯函数编程原则。以下内容可用于描述 let 表达式:

如果一个表达式在计算时没有改变机器的观察状态并且针对相同的输入产生相同的值,则该表达式的求值不会产生副作用。

同时,引用维基百科的说法:

非纯函数式语言提供了单赋值和真正的赋值(尽管真正的赋值在命令式编程语言中的使用频率通常比它低)。例如,在 Scheme 中,所有变量都可以使用单赋值(使用 let)和真正的赋值(使用 set!),并为列表、向量、字符串等提供了专门的原始操作以进行破坏性更新。


1
一种函数式编程语言鼓励并提供了函数式编程的特性,但并不一定强制要求使用函数式编程。 - ThePiercingPrince
仅仅因为Scheme不强制要求函数式编程风格,并不意味着将其称为函数式编程语言是错误的。它确实提供了使用命令式操作(例如set,改变环境以影响状态)的能力,但它并没有像循环等完整的功能集,因此Scheme是一种函数式编程语言,提供了一些命令式特性。 - NeoH4x0r
@NeoH4x0r,实际上Scheme确实提供了传统的循环(请参见“do”循环),并且根据方言,还提供了相当广泛的“for”循环结构。我认为这是一组相当完整的命令式特性 :)。告诉我你认为缺少的一个特性,我敢打赌我可以为你找到它! - Óscar López
@Óscar López,即使它提供了一些命令式特性,仍然不会使将if称为函数语言不正确。 - NeoH4x0r

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接