例如,我会写:
x = 2
y = x + 4
print(y)
x = 5
print(y)
它会输出:
6 (=2+4)
9 (=5+4)
此外,在任何情况下这实际上可能有用吗?
澄清:是的,lambdas 等解决了这个问题(他们是我如何得出这个想法的);我想知道是否存在默认的特定语言:不需要或不需要函数或 lambda 关键字。
例如,我会写:
x = 2
y = x + 4
print(y)
x = 5
print(y)
它会输出:
6 (=2+4)
9 (=5+4)
此外,在任何情况下这实际上可能有用吗?
澄清:是的,lambdas 等解决了这个问题(他们是我如何得出这个想法的);我想知道是否存在默认的特定语言:不需要或不需要函数或 lambda 关键字。
Haskell 将在中途遇见你,因为本质上一切都是一个函数,但变量只绑定一次(这意味着你不能x
在同一范围内重新分配)。
考虑变量赋值很容易y = x + 4
,但是当您查看y = map (+4) [1..]
(这意味着从 1 向上的无限列表中的每个数字添加 4)时,现在是y
什么?它是一个无限列表,还是一个返回无限列表 的函数?(提示:这是第二个。) 在这种情况下,将变量视为函数可能是非常有益的,如果不是绝对必要的话,当利用惰性时。
实际上,在 Haskell 中,您的定义y
是一个不接受参数并返回的函数x+4
,其中x
也是一个不接受参数但返回值 2 的函数。
在任何具有一阶函数的语言中,将匿名函数分配给变量是微不足道的,但对于大多数语言,您必须添加括号来表示函数调用。
示例 Lua 代码:
x = function() return 2 end
y = function() return x() + 4 end
print(y())
x = function() return 5 end
print(y())
$ lua x.lua 6 9
或者在 Python 中也一样(坚持使用一阶函数,但我们可以只使用普通整数x
):
x = lambda: 2
y = lambda: x() + 4
print(y())
x = lambda: 5
print(y())
$蟒蛇x.py 6 9
您可以在 C# 中使用 func 表达式
Func<int, int> y = (x) => x + 5;
Console.WriteLine(y(5)); // 10
Console.WriteLine(y(3)); // 8
... 或者 ...
int x = 0;
Func<int> y = () => x + 5;
x = 5;
Console.WriteLine(y()); // 10
x = 3;
Console.WriteLine(y()); // 8
...如果您真的想以功能样式进行编程,那么第一个选项可能是最好的。
查看各种函数式语言,如 F#、Haskell 和 Scala。Scala 将函数视为具有 apply() 方法的对象,您可以将它们存储在变量中并像传递任何其他类型的对象一样传递它们。我不知道您是否可以将 Scala 函数的定义打印为代码。
更新:我似乎记得至少有一些 Lisps 允许您将函数漂亮地打印为代码(例如,Scheme 的漂亮打印函数)。
这就是电子表格的工作方式。
它还与用于评估函数参数的按名称调用语义有关。Algol 60 有,但没有流行起来,实施起来太复杂了。
编程语言Lucid做到了这一点,尽管它调用x
和y
“流”而不是函数。该程序将被编写:
y
where
y = x + 4
end
然后你会输入:
x(0): 2
y = 6
x(1): 5
y = 7
当然,Lucid(就像大多数有趣的编程语言一样)相当晦涩难懂,所以我对没有人发现它并不感到惊讶。(或寻找它)
我见过的最接近这些的是图表组件中的技术分析系统的一部分。(Tradestation、metastock 等),但主要集中在返回多组元数据(例如买入/卖出信号),然后可以将这些元数据输入其他接受元数据或财务数据或直接绘制的函数。
我的 2c:我会说一种你建议的语言,至少可以说是非常令人困惑的。函数通常是 r 值,这是有充分理由的。此代码 (javascript) 显示了将函数作为 r 值执行如何增加 n 倍的可读性(并因此提高维护):
var x = 2;
var y = function() { return x+2; }
alert(y());
x= 5;
alert(y());
self不区分字段和方法,两者都是插槽,可以以完全相同的方式访问。一个槽可以包含一个值或一个函数(因此这两个仍然是独立的实体),但区别对槽的用户来说并不重要。
在 Scala 中,函数中有惰性值和按名称调用的参数。
def foo(x : => Int) {
println(x)
println(x) // x is evaluated again!
}
在某种程度上,这可能会产生您想要的效果。
我相信像Octave、R和Maxima这样的面向数学的语言可以做到这一点。我可能是错的,但没有其他人提到它们,所以我想我会的。