【发布时间】:2014-07-18 19:31:36
【问题描述】:
我研究了 Erlang,对变量的重新分配感到困惑,例如计数器是可能的:
循环(值,计数器)-> io:format("~s,~n",[值]), 循环(值,Counter-1)。
我希望看到一种纯粹的函数式语言。 或者,我应该转移我的 POV 吗?
干杯,
托马斯
【问题讨论】:
标签: erlang
我研究了 Erlang,对变量的重新分配感到困惑,例如计数器是可能的:
循环(值,计数器)-> io:format("~s,~n",[值]), 循环(值,Counter-1)。
我希望看到一种纯粹的函数式语言。 或者,我应该转移我的 POV 吗?
干杯,
托马斯
【问题讨论】:
标签: erlang
Counter-1 是一个新值,未分配给任何现有变量。【讨论】:
loop(Value,Counter)-> io:format("~s,~n",[Value]), loop(Value,Counter-1).
在上面的函数定义中,函数本身的名称出现在定义的右侧,并且使用相同的arity。我们称这种类型的定义为递归定义。每个递归调用都将定义一个名为Counter 的值,该值仅在当前递归级别中可见。换句话说,与表达式 Counter - 1 的求值对应的数字将绑定到一个 new Counter 变量,在范围方面与表达式中使用的变量无关。
但是,这种类型的递归函数调用称为tail-recursive。这是一种特定类型的调用,具有可优化到真实循环的特性。最终结果是函数使用的Counter 的内存单元将使用新值更新并用于递归调用,而不是为新的Counter 值再次分配(1)。这允许潜在的无限递归方案。
关于函数式语言的概念,如果不首先正确定义什么是函数式语言,以及什么是纯函数式,就很难回答这个问题。
在我的书中,函数式语言是一种基于 lambda 演算概念的语言:函数抽象和应用,高阶函数:这也称为函数作为语言的一等公民。 Erlang 绝对适合该模型。纯 FL 可能不支持另一种主要的编程范式,即命令式(可变可变性)。 Erlang 再次符合这个定义。如果你有不同的定义,那么Erlang的情况可能会有所不同。
Pascal 在 cmets 部分指出,Erlang 中有一个不遵循纯函数式语言范式的工具: Process dictionaries。实际上,可以在该结构中设置值,如前所述:
注意使用过程字典:
破坏参考透明度
使调试变得困难
在接球/投掷中幸存下来
(强调我的)。
因此,Erlang 不是严格纯粹的。
(1) 尾递归并不是实现该优化的唯一方法:请参阅 http://learnyousomeerlang.com/recursion
【讨论】: