【问题标题】:How to fix the infinite loop error of "f = lambda x: f(x)+1" in a functional programming language?如何修复函数式编程语言中“f = lambda x: f(x)+1”的无限循环错误?
【发布时间】:2021-09-05 15:57:24
【问题描述】:

考虑以下python中的代码:

f = λx: x

f = λx: f(x)+1

f(1)

Python 在运行最后一行时抛出一个“无限循环”错误,这在它将第二行解释为 f 的递归公式的方式上很明显。

但是,如果将 f 的“值”替换为右侧的“值”,然后将结果函数分配给 f(在左侧),则第二行似乎是合理的。

是否存在通过 lambda 演算操作在 python(或其他可以处理函数的语言)中修复此错误的直接方法?

我问这个问题只是为了更好地了解函数式语言,但在我看来,答案有助于对函数进行循环计算!

【问题讨论】:

  • 说明显而易见的风险:(1)在这两个分配之间添加g = f,(2)用@替换第二个分配右侧的所有f 987654324@。这样,您可以通过中间变量“修复”f 的值。在真正函数式语言中,您不会遇到这个问题,因为大多数值是不可变的,因此您不会“重新分配”f
  • @Heinzi 似乎这在python中不起作用。它在另一个程序中工作吗? (像斯卡拉?)
  • 修复此错误”是什么意思?只是不要写有这个错误的代码吗?您是否正在尝试创建一个检测此类错误的 linter?您是否正在尝试创建一个可以自动将 python 代码重写为您想要的含义的工具?
  • @Mostafa:在这种情况下,= 并不意味着等于。这意味着“将右侧的任何内容存储在左侧的变量中”。一些编程语言使用左箭头代替,这使得这一点更加明确:g ← f。因此,g 现在包含您的“旧” lambda 和 f 新的(比较它与 f = 2; g = f; f = 3 - 现在 g 包含 2 并且 f 包含 3)。请注意,lambda 使一切变得更加复杂,因为它们创建了“闭包”和“捕获变量”。您可以使用这些搜索词进行进一步研究。

标签: functional-programming lambda-calculus


【解决方案1】:

当然。在 Lisp/Scheme 系列中,您可以为此使用 let*

(let* ((f (lambda (x) x))
       (f (lambda (x) (+ (f x) 1))))
  (display (f 1)))

请注意,除了前缀符号之外,您会发现 Scheme 语法更接近 lambda-calculus。 let* 构造按顺序定义名称,允许在第二个的主体中使用第一个名称,即使您“隐藏”它也是如此。

在 Python 中,您必须单独命名函数,如下所示:

f0 = lambda x: x
f1 = lambda x: f0(x) + 1
print(f1(1))

如果您想研究 lambda 演算,尤其是无类型的类型,Scheme 是您的最佳选择,因为大多数 lambda 演算结构将直接映射到它,以前缀语法为模。对于类型化的 lambda 演算,一个不错的选择是像 Haskell 这样的语言。我个人不会使用 Python 来学习函数式编程,因为它将两种风格混为一谈,这将被证明是一种障碍;虽然当然是可行的。

【讨论】:

  • 感谢@alias 提供了这个非常有启发性的答案!
猜你喜欢
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 2014-04-16
相关资源
最近更新 更多