【问题标题】:Are there any programming languages where variables are really functions?是否有任何编程语言中变量是真正的函数?
【发布时间】:2009-10-07 02:01:59
【问题描述】:

例如,我会写:

x = 2
y = x + 4
print(y)
x = 5
print(y)

它会输出:

6 (=2+4)
9 (=5+4)

另外,在任何情况下这实际上可能有用吗?

澄清:是的,lambdas 等解决了这个问题(他们是我如何得出这个想法的);我想知道是否有特定的语言,这是 默认:不需要或不需要函数或 lambda 关键字。

【问题讨论】:

标签: programming-languages variables function dataflow


【解决方案1】:

Haskell 会遇到一半,因为本质上一切都是函数,但变量只绑定一次(这意味着您不能在同一范围内重新分配 x)。

很容易将y = x + 4 视为变量赋值,但是当您查看y = map (+4) [1..](这意味着从1 向上的无限列表中的每个数字添加4)时,y 现在是什么?它是一个无限列表,还是一个返回无限列表的函数(提示:这是第二个。) 在这种情况下,当利用laziness 时,将变量视为函数可能非常有益,如果不是绝对必要的话。

真的,在 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

【讨论】:

  • Algol68 (1968) 是强类型的,允许声明函数变量,例如: MODE FUN = PROC INT;乐趣 x := INT:2;有趣的 := INT:x + 4;打印(y); x := INT:5; print(y) ... 产生:+6 +9 ... c.f. Sourceforge:[sourceforge.net/projects/algol68]
【解决方案2】:

你可以在 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

...如果您真的想以功能样式进行编程,第一个选项可能是最好的。

  1. 它看起来更像你在数学课上看到的东西。
  2. 您不必担心外部状态。

【讨论】:

    【解决方案3】:

    查看各种函数式语言,例如 F#、Haskell 和 Scala。 Scala 将函数视为具有 apply() 方法的对象,您可以将它们存储在变量中并像传递任何其他类型的对象一样传递它们。我不知道你可以把Scala函数的定义打印成代码。

    更新:我似乎记得至少有一些 Lisps 允许您将函数漂亮地打印为代码(例如,Scheme 的漂亮打印函数)。

    【讨论】:

      【解决方案4】:

      这就是电子表格的工作方式。

      它还与评估函数参数的call by name 语义有关。 Algol 60 有这个功能,但并没有流行起来,实施起来太复杂了。

      【讨论】:

        【解决方案5】:

        编程语言Lucid 执行此操作,尽管它调用xy“流”而不是函数。 该程序将被编写:

        y
          where
            y = x + 4
          end
        

        然后你会输入:

         x(0): 2
           y = 6
         x(1): 5
           y = 7
        

        当然,Lucid(就像大多数有趣的编程语言一样)相当晦涩,所以没有人发现它我并不感到惊讶。 (或寻找它)

        【讨论】:

          【解决方案6】:

          尝试查看 F# hereWikipedia 了解函数式编程语言。

          自从我专注于 OOP 以来,我自己还没有研究过这些类型的语言,但是一旦 F# 出来,我很快就会深入研究。

          希望这会有所帮助!

          【讨论】:

          • 据我了解,F# 已经发布,直到 2010 年它才正式成为 Visual Studio 的一部分
          • 尚未发布 - 2008 年的版本仍然是“CTP”。
          【解决方案7】:

          我所见过的最接近的是图表组件中技术分析系统的一部分。 (Tradestation、metastock 等),但它们主要侧重于返回多组元数据(例如买入/卖出信号),然后可以将这些元数据输入其他接受元数据或财务数据或直接绘制的函数。

          我的 2c: 我会说一种你所建议的语言,至少可以说是非常令人困惑的。函数通常是 r 值,这是有充分理由的。这段代码 (javascript) 展示了如何将函数作为 r 值来增加可读性(从而增加维护)n 倍:

          var x = 2;
          var y = function() { return x+2; }
          alert(y());
          x= 5;
          alert(y());
          

          【讨论】:

            【解决方案8】:

            Self 不区分字段和方法,两者都是插槽,可以以完全相同的方式访问。一个槽可以包含一个值或一个函数(因此这两个仍然是独立的实体),但区别对槽的用户来说并不重要。

            【讨论】:

              【解决方案9】:

              在 Scala 中,函数中有惰性值和按名称调用的参数。

              def foo(x : => Int) {
                  println(x)
                  println(x) // x is evaluated again!
              }
              

              在某种程度上,这可能会产生您想要的效果。

              【讨论】:

                【解决方案10】:

                我相信像 OctaveRMaxima 这样的面向数学的语言可以做到这一点。我可能是错的,但没有其他人提到它们,所以我想我会的。

                【讨论】:

                  猜你喜欢
                  • 2018-12-09
                  • 2010-09-28
                  • 1970-01-01
                  • 2019-12-05
                  • 1970-01-01
                  • 2011-03-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多