函数参数可以自由互换而不影响程序行为吗?
Can function arguments be freely interchanged without affecting program behaviour?
这是一个适用于具有函数(无可选参数)的静态类型语言的问题。
如果我有一些函数接受 a、b、c、d、e 类型的 5 个参数,格式如下:
function(a, b, c, d, e) {
does things
}
// call syntax:
function(a, b, c, d, e);
如果我修改函数以接受不同顺序的参数(假设我按该顺序调用它),它(理论上)是否等效?
function(e, a, d, b, c) {
does things
}
// call syntax:
function(e, a, d, b, c);
关于这个问题是否有实际的学术工作,或者答案应该是微不足道的? (我没有使用正式编程语言的经验)
奇怪的问题...无论如何:从形式的角度来看,是的,这两个声明是等价的,因为你只是改变了参数的名称:
function(a, b, c) { ...
与
相同
function(b, a, c) { ...
原来的正式名字“a”现在是b,名字“b”变成了a。
形式参数是“形式”...
但是您可能无法在不更改正文的情况下更改声明,即:
function divide(a,b) { return a / b }
不等于:
function divide(b,a) { return a / b }
在您的示例中,您更改了 声明 和 调用...只要交换的类型有效参数是相同的,但当类型不同时它并不总是有效,因为你可以在一个类型上做的事情可能会被禁止或在另一种类型上表现不同。
如果在该语言中,参数可以是函数调用,并且这些函数可以有副作用,那么将这些参数按不同的顺序放置可能会导致不同的行为。 (语言定义可能会说在这种情况下行为是未定义的。)
如果您扩展语言语义以允许使用默认参数或部分函数应用程序,那么顺序很可能会开始发挥作用。这些问题可以通过提供关键字参数来解决,除非参数顺序变得重要。
默认参数
假设您有函数定义-
function(a, b, c, d=1, e=2) {
does things
}
现在,如果您想将 d
保留为其默认值但为 e
传递参数,则需要支持将 e
作为关键字参数传递,或重新排序参数,使 e
在参数列表中位于 d
之前。
此外,如果我们想为 b
提供默认值,我们必须将其移动到参数列表中的 c
之后,否则调用函数的唯一方法是b
因为它的默认设置是通过关键字提供 c
。
部分函数应用
假设您想将 a
和 b
部分应用到您的 function
。我们可以做到这一点,并获得一个函数,我们可以将其余参数应用到该函数。
g = function(a, b)
g(c, d, e)
但是,如果我们只想部分应用 d
和 e
,那么如果没有关键字参数,我们将无法做到这一点。
这是一个适用于具有函数(无可选参数)的静态类型语言的问题。
如果我有一些函数接受 a、b、c、d、e 类型的 5 个参数,格式如下:
function(a, b, c, d, e) {
does things
}
// call syntax:
function(a, b, c, d, e);
如果我修改函数以接受不同顺序的参数(假设我按该顺序调用它),它(理论上)是否等效?
function(e, a, d, b, c) {
does things
}
// call syntax:
function(e, a, d, b, c);
关于这个问题是否有实际的学术工作,或者答案应该是微不足道的? (我没有使用正式编程语言的经验)
奇怪的问题...无论如何:从形式的角度来看,是的,这两个声明是等价的,因为你只是改变了参数的名称:
function(a, b, c) { ...
与
相同function(b, a, c) { ...
原来的正式名字“a”现在是b,名字“b”变成了a。
形式参数是“形式”...
但是您可能无法在不更改正文的情况下更改声明,即:
function divide(a,b) { return a / b }
不等于:
function divide(b,a) { return a / b }
在您的示例中,您更改了 声明 和 调用...只要交换的类型有效参数是相同的,但当类型不同时它并不总是有效,因为你可以在一个类型上做的事情可能会被禁止或在另一种类型上表现不同。
如果在该语言中,参数可以是函数调用,并且这些函数可以有副作用,那么将这些参数按不同的顺序放置可能会导致不同的行为。 (语言定义可能会说在这种情况下行为是未定义的。)
如果您扩展语言语义以允许使用默认参数或部分函数应用程序,那么顺序很可能会开始发挥作用。这些问题可以通过提供关键字参数来解决,除非参数顺序变得重要。
默认参数
假设您有函数定义-
function(a, b, c, d=1, e=2) {
does things
}
现在,如果您想将 d
保留为其默认值但为 e
传递参数,则需要支持将 e
作为关键字参数传递,或重新排序参数,使 e
在参数列表中位于 d
之前。
此外,如果我们想为 b
提供默认值,我们必须将其移动到参数列表中的 c
之后,否则调用函数的唯一方法是b
因为它的默认设置是通过关键字提供 c
。
部分函数应用
假设您想将 a
和 b
部分应用到您的 function
。我们可以做到这一点,并获得一个函数,我们可以将其余参数应用到该函数。
g = function(a, b)
g(c, d, e)
但是,如果我们只想部分应用 d
和 e
,那么如果没有关键字参数,我们将无法做到这一点。