【发布时间】:2012-11-02 11:44:39
【问题描述】:
让我们考虑一个例子:我想打开/关闭一个灯泡。在 C 中,我可以写:
struct lightbulb {
int is_turned_on;
/* from 1 to 10 */
int light_intensity;
};
每当我想打开或关闭灯泡时,我都会将 is_turned_on 更改为 1,并通过将 light_intensity 从 1(最暗)设置为 10(最亮)来更改它的亮度。
如何在函数式编程中做同样的事情?我想我必须创建一个列表来保存这些值,创建一个函数 ON 和 OFF 来“打开”/关闭灯泡,以及一个返回灯泡光强度的函数。每次调用该函数时,都会返回一个新灯泡:
(defun turn-on()
'(1 0))
(defun turn-off()
'(0 0))
(defun light-intensity (x)
`(0 ,(eval x)))
我可以看到像光强度这样的函数是一个类似于线性函数的连续函数。无论我们为每个 x 传递相同的参数 x 多少次,它都会评估相同的结果。每个函数的结果是一个具有不同状态的新灯泡。
问题是,我怎样才能持久化状态?显然,我必须通过变量将它存储在我记忆中的某个地方。
更新:我通过c2 Wiki - Functional Programming找到了上述问题的答案
数据项如何保留?
在堆栈上。在顺序批处理程序中,数据被初始化并 转换为顶级函数。在一个长期存在的程序中,比如 服务器,递归调用顶层循环函数,传递 从一次调用到下一次调用的全局状态。
我还得在每次调用函数的时候创建一个新对象(list),如何销毁之前的旧对象呢?
仅仅通过defparameter 和setf 改变变量不是更高效更简单吗?想象一下,如果它不是一个灯泡,而是一个包含更多信息的更复杂的物体?如何将其建模为函数?
【问题讨论】:
-
您的 C 代码和您的 Common Lisp 代码都不正确。在 C 中,您不能在
struct声明中分配字段。在 Lisp 中你不能申请0。而且我不明白你在问什么......可变数据并不是真正的函数式编程。 -
哦,我忘了。我打算写一个主函数,但不知何故决定不写,并与结构声明混为一谈。我会修复的。但是关于 Lisp 代码,这就是我所理解的。我研究了一段时间的 Common Lisp,而不是 Scheme。
-
我在问如何使用纯函数式编程有效地处理状态,而不需要另一个副本只是为了使其“引用透明”?通过阅读论文“为什么函数式编程很重要”,该论文表明没有赋值不是 FP 的优势。
-
Btw Lisp 代码在 CLISP 解释器中正确执行。