一般来说,我们都听说过编程语言中的函数或过程。然而,我发现我几乎可以互换地使用这些术语(这可能是非常错误的)。

我的问题是:

它们的功能、目的和用途有什么不同?

请举例说明。


当前回答

我反对在大多数答案中反复看到的东西,函数之所以成为函数,是因为它返回一个值。

函数不是任何返回值的旧方法。事实并非如此:为了让一个方法成为一个实函数,它必须总是在给定特定输入的情况下返回相同的值。不是函数的方法的一个例子是大多数语言中的随机方法,因为尽管它确实返回值,但值并不总是相同的。

因此,函数更类似于映射(例如,对于一维函数,x -> x')。这是常规方法和函数之间的一个非常重要的区别,因为当处理实函数时,它们被求值的时间和顺序应该永远不重要,因为对于非函数并不总是如此。

这是另一个方法的例子,它不是函数,但仍然会返回一个值。

// The following is pseudo code:
g(x) = {
  if (morning()) {
     g = 2 * x;
  }
  else {
   g = x;
  }
  return g;
}

我进一步反对过程不返回值的概念。过程只是谈论函数或方法的一种特定方式。这意味着如果你的过程定义或实现的底层方法返回一个值,那么猜猜这个过程返回什么值。以SICP中的以下片段为例:

// We can immediately translate this definition into a recursive procedure 
// for computing Fibonacci numbers:

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib (- n 1))
                 (fib (- n 2))))))

您最近听说过递归过程吗?他们在讨论一个递归函数(一个实函数),它返回一个值,他们使用了“过程”这个词。那么,有什么不同呢?

另一种思考函数的方式(除了上面提到的意义)是作为一个理想的抽象表示,如数字1。过程就是那个东西的实际实现。我个人认为它们是可以互换的。

(注意,如果你从我提供的链接中阅读了那一章,你可能会发现更难理解的概念不是函数和过程之间的区别,而是过程和过程之间的区别。你知道递归过程可以有迭代过程吗?)

过程的类似物是配方。例如;假设你有一台叫派的机器,这台机器输入(水果、牛奶、鲜花、鸡蛋、糖、热量)的原料,然后这台机器返回一个派。

这台机器的表示可能是这样的

make-pies (fruit, milk, flower, eggs, sugar, heat) = {
   return (heat (add fruit (mix eggs flower milk)))
}

当然,这不是做派的唯一方法。

在这个例子中,我们可以看到:

A       function     is to a     machine
as a    procedure    is to a     recipe
as      attributes   are to      ingredients
as      output       is to       product

这个类比是可以的,但当你考虑到当你在处理一个计算机程序时,一切都是抽象的,它就不成立了。所以不像机器的配方我们比较的是两个本身就是抽象的东西;这两件事很可能是同一件事。我认为它们(出于所有意图和目的)是同一件事。

其他回答

如果我们在这里与语言无关,那么过程通常指定了可靠且幂等地实现某个结果所需的一系列行为。也就是说,一个过程基本上就是一个算法。

另一方面,函数是较大程序中某种程度上独立的代码段。换句话说,函数是过程的实现。

这取决于上下文。

在类pascal语言中,函数和过程是不同的实体,不同之处在于它们是否返回值。他们的行为不同。语言语法(例如;过程调用表单语句;你不能在表达式中使用过程调用,而函数调用不构成语句,你必须在其他语句中使用它们)。因此,pascal培养的程序员会对这两者进行区分。

在类c语言和许多其他当代语言中,这种区别已经不复存在;在静态类型语言中,过程只是带有有趣返回类型的函数。这可能就是为什么它们可以互换使用的原因。

在函数式语言中,通常没有过程这样的东西——所有东西都是函数。

Function可以在sql语句中使用,而procedure不能在sql语句中使用。

插入、更新和创建语句不能包含在函数中,但过程可以包含这些语句。

过程支持事务,但函数不支持事务。

函数必须返回一个且仅返回一个值(另一个值可以由OUT变量返回),但过程返回尽可能多的数据集和返回值。

函数和过程的执行计划都被缓存,因此在这两种情况下性能是相同的。

C语言示例:

// function
int square( int n ) {
   return n * n;
}

// procedure
void display( int n ) {
   printf( "The value is %d", n );
}

尽管你应该注意到C标准没有谈论过程,只有函数。

过程和函数都是子例程,它们之间的唯一区别是过程返回多个(或至少可以执行)值,而函数只能返回一个值(这就是为什么在数学中使用函数表示法,因为在给定的时间通常只找到一个值),尽管一些编程语言不遵循这些规则,这是它们的真正定义