(SICP) 函数和过程之间有什么区别?

3

我目前正在阅读《计算机程序的构造和解释》这本书,并且同时听布莱恩·哈维的讲座(他有时候很搞笑),但是我还没有真正领悟到区分函数和过程的“啊哈!时刻”。

现在,我已经在课程和阅读之外进行了研究,并找到了几篇关于同一问题的不同帖子,但是似乎都分成了单独的讨论/意见,涉及真正的解释或过时的定义。我看到的一个普遍答案是函数返回值而过程不返回,但这并没有为我解决多少问题,大多数回答用户也都对这个答案提出了一些质疑。

在文本和讲座中深入研究高阶过程,我完全理解了这个概念以及它所提供的强大功能,但我感到困惑的是,我会听到“高阶过程”和“高阶函数”。布莱恩·哈维还提到,“高阶过程表示高阶函数”。

我理解下面两个函数是相同的函数,但是过程不同。

f(x) = 2x + 6
g(x) = 2(x + 3)

现在,下面将make-adder称为一个具有num作为形式参数的过程。make-adder的定义域是数字,范围是过程。我想真正让我困惑的是,他将lambda表达式称为恰好那个lambda表达式,但是make-adder返回的是一个过程?
(define (make-adder num)
  (lambda (x) (+ x num))

(define plus3 (make-adder 3))
(plus3 8)

我原本以为自己很清楚,直到在高阶过程课程中提到了一些过程的参考,这让我感到困惑了。

请问能否给出一个可能的例子来区分这两个概念?谢谢!

1个回答

4

TL; DR: 在SICP的上下文中,过程(procedure)和函数(function)指的是同一件事情。

在数学中,函数是一个接受参数并返回值的东西,并且对于相同的参数总是返回相同的值。你可以把它替换为从参数到结果的映射。

在Scheme或JavaScript等编程语言中,使用function这个词并不适用于具有某种副作用或返回值与参数不一致的所有代码。

过程(procedure)是一个更通用的术语,因此您不能说一个过程需要具有引用透明性(reference transparency),以便将其视为数学函数,因此Scheme和JavaScript都有过程(procedures),而不是函数(functions)。例如,在x86 Intel平台上,子例程(subroutine)是一个过程。它不允许参数,并且没有返回值,只能跳转和返回。但是,C使用代码来操作堆栈(stack)以传递参数并获得返回值,在这种意义上,您可以模拟“函数”,但他们并没有删除每个输入的返回值可能不相同的可能性,因此您可以实现不是函数的“c函数”,但仍然可以称之为过程。


1
谢谢,这确实有帮助。现在我可以正确地假设很多程序员在本不应该互换使用这些术语的情况下,却经常这样做吗? - Benjamin Arsenault
1
@BenjaminArsenault 我遵循编程语言的命名惯例,以避免混淆。例如,在Scheme中它被称为procedure,在Common Lisp和Racket中它被称为function。有些人可能在没有可观察到的副作用时称之为函数,而在有副作用时称之为过程,但是有很多文本都将两者都称为函数,并使用纯函数一词来指示“真正”的函数。 - Sylwester
感谢您抽出时间回答问题,这对我帮助很大。 - Benjamin Arsenault

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接