我正在读一本关于λ微积分的书“通过Lambda微积分进行功能编程”(格雷格·迈克尔森)。在书中,作者介绍了用于定义函数的简写形式。例如
def identity = λx.x
并继续说,我们应该坚持使用这样的速记法:“在定义表达式之前,所有定义的名称都应替换为它们的定义 ”
后来,当介绍递归时,他以加法函数的定义为例:
def add x y = if iszero y then x else add (succ x) (pred y)
并说,如果没有上述限制,我们可以通过缓慢扩展它来评估该功能。但是,由于在表达式的求值之前我们必须替换所有已定义的名称,因此我们不能这样做,因为我们继续不确定地替换add
,因此需要更详细地考虑递归。
因此,我的问题如下:对自己施加限制的理论或实践原因是什么? (必须在函数评估之前 替换所有定义的名称)?有吗
答案 0 :(得分:3)
我试图展示如何从一个非常简单的语言构建一个丰富的语言,通过添加连续的语法层,其中每一层都可以翻译成上一层。因此,重要的是将必须终止的翻译与不需要的评估区分开来。我认为递归可以翻译成非递归真的很有趣。如果我的解释没有帮助,我很抱歉。
答案 1 :(得分:0)
原因是我们希望保持在lambda演算规则之内。允许术语的名称表示除立即替换之外的任何含义,这意味着在该语言中添加recursive let expression,这意味着我们将需要一个真正更具表达能力的系统(不再是lambda演算)。
您可以认为原始lambda术语的名称最多不超过syntactic sugar。 Y组合器正是将递归引入没有内置递归的系统的方法。 如果您当前正在阅读的书使您感到困惑,则可能需要在互联网上搜索一些其他有关Y组合器的资源。
答案 2 :(得分:0)
我将尝试以我理解的方式发布自己的答案。
对于无类型的lambda演算,没有实用原因,我们需要Y组合器。 practical 的意思是,如果某人想要构建一个表达式评估器,则可以在不需要组合器且仅缓慢扩展定义的情况下进行。
不过,出于理论上的原因,我们需要确保在定义函数时,该定义具有一定的含义,并且并未就其本身进行定义。例如以下定义没有太多含义:
def something = something
由于这个原因,我们需要查看是否有可能以非自引用的方式重写定义,即可以定义某些内容而不引用其自身。事实证明,在无类型lambda演算中,我们始终可以通过Y组合器来做到这一点。
使用Y组合器,我们总是可以构造方程x = f(x)= f(f(x))= ... = f(f(f(f(x())))=的解。 ...对于任何f,
即我们总是可以将自引用定义重写为不包含自身的定义