我现在才开始讨论这个问题,但是我想为那些正在与函数式编程作斗争的人补充几点。
函数式语言维护与命令式语言完全相同的状态更新,但它们是通过将更新后的状态传递给后续的函数调用来实现的。这是一个沿着数轴移动的简单例子。您的状态是您当前的位置。
首先是命令式方式(在伪代码中)
moveTo(dest, cur):
while (cur != dest):
if (cur < dest):
cur += 1
else:
cur -= 1
return cur
现在是函数式的方式(在伪代码中)。我非常依赖三元运算符,因为我希望有命令式背景的人能够读懂这段代码。所以如果你不经常使用三元运算符(我总是避免它在我的命令式的日子)下面是它是如何工作的。
predicate ? if-true-expression : if-false-expression
您可以通过将一个新的三元表达式放在假表达式的位置来连接三元表达式
predicate1 ? if-true1-expression :
predicate2 ? if-true2-expression :
else-expression
考虑到这一点,下面是函数版本。
moveTo(dest, cur):
return (
cur == dest ? return cur :
cur < dest ? moveTo(dest, cur + 1) :
moveTo(dest, cur - 1)
)
这是一个简单的例子。如果这是在游戏世界中移动人,你就必须引入一些副作用,如在屏幕上绘制对象的当前位置,并根据对象移动的速度在每次调用中引入一些延迟。但你仍然不需要可变状态。
The lesson is that functional languages "mutate" state by calling the function with different parameters. Obviously this doesn't really mutate any variables, but that's how you get a similar effect. This means you'll have to get used to thinking recursively if you want to do functional programming.
Learning to think recursively is not hard, but it does take both practice and a toolkit. That small section in that "Learn Java" book where they used recursion to calculate factorial does not cut it. You need a toolkit of skills like making iterative processes out of recursion (this is why tail recursion is essential for functional language), continuations, invariants, etc. You wouldn't do OO programming without learning about access modifiers, interfaces etc. Same thing for functional programming.
我的建议是做小Schemer(注意我说的是“做”而不是“读”),然后做SICP的所有练习。当你完成时,你的大脑会和刚开始时不一样。