2

这是一个重新打开的问题。

我为它寻找一种语言和支持平台,默认情况下该语言可以具有传递引用或传递名称语义。我知道一点历史,有 Algol、Fortran,还有 C++ 可以使它成为可能;但是,基本上,我寻找的是更现代的东西,并且在默认情况下,首选提到的值传递方法(假设)。

我问这个问题,因为在我看来,pass-by-ref/name 的一些优点似乎很明显。例如,当它用于独立代理时,不需要复制值(在某种程度上),并且在这种情况下性能不会降级很多。因此,我可以在富客户端应用程序或一些游戏风格或独立服务类应用程序中使用它。

对我来说,主要优势是符号的身份与其当前值之间的明确分离。我的意思是当没有冗余复制时,您知道您正在使用您查询/接收的确切符号/路径。并且对值进行装箱不会干扰程序的实际逻辑。

我知道有 C#ref关键字,但它不是那么内在,虽然可以接受。同样,我意识到引用传递语义几乎可以用任何语言模拟(Java 作为一个即时示例)等等.. 不确定通过名称传递:)

你会推荐什么 - 在适当的地方为此类需求创建类似 DSL 的东西;或者使用一些我已经知道的语言?也许,我错过了什么?

谢谢!

更新:目前,我认为 Haskell 是合适的。但是我没有做太多调查,所以我想我会在以后更新这个文本。

4

6 回答 6

5

Scala提供了非常灵活的参数传递语义,包括真正的按名称调用

def whileLoop(cond: => Boolean)(body: => Unit) {
  if (cond) {
    body
    whileLoop(cond)(body)
  }
}

它确实有效

var i = 10
whileLoop (i > 0) {
  println(i)
  i -= 1
}

技术细节:虽然所有参数都像 Java 一样按值传递(这些通常是引用),但这种表示法=> Type将使 Scala 自动生成所需的闭包,以模拟按名称调用。

请注意,也有惰性评估

lazy val future = evalFunc()


有趣的是,您具有一致的严格按值调用语义,但可以在您真正需要的地方准时更改这些语义——几乎没有任何语法开销。

于 2010-05-23T09:01:05.133 回答
4

路过的名字现在已经很少见了。但是,您可以使用 lambda-nill 在大多数函数式编程语言中模拟它:

// Pass by value
(dosomething (random))
// Pass by name hack
(dosomething (lambda () (random)))

除此之外:ML 和 O'CaML 在按值传递(默认)、按引用传递(使用 ref 变量)和当然使用 lambda 之间有区别。但是,我不确定它们中的任何一个都符合“现代”语言的条件。

于 2010-05-23T07:12:01.470 回答
4

Haskell 将按需调用作为其默认(实际上是唯一的)评估策略。

现在,您要了两件事:按名称调用和现代。好吧,Haskell 是一种纯语言,在纯语言中,按名称调用和按需调用在语义上是相同的,或者更准确地说,它们总是具有相同的结果,唯一的区别是按需调用是通常更快,最坏的情况是比按名称调用慢的常数因子。而 Haskell 无疑是​​一门现代语言:它只有 23 年的历史,而且它的许多功能实际上比最近创建的许多语言早了 10 年。

你问的另一件事是引用调用。同样,在纯语言中,按值调用和按引用调用是同一件事,只是后者更快。(这就是为什么,尽管大多数函数式语言通常被描述为按值调用,但它们实际上实现了按引用调用。)

现在,按名称调用(以及按需要按扩展调用)按值调用(和按引用按扩展调用)不同,因为按名称调用可能会返回结果按值调用不会终止的情况。

但是,在按值调用或按引用调用终止的所有情况下,在纯语言中,按值调用、按引用调用、按名称调用和按需要调用是相同的事物。在它们不是同一件事的情况下,按名称调用和按需要调用在某种意义上“更好”,因为它们在按值调用和按引用调用的情况下会给你一个答案基本上会陷入无限循环。

因此,Haskell 是您的答案。虽然可能不是您要找的那个:-)

于 2010-05-23T08:00:32.693 回答
2

ref对于 C#和out修饰符不是“内在”的原因,我并没有完全遵循您的推理。在我看来,它几乎提供了您正在寻找的东西:一种支持按值传递和按引用传递的现代语言和环境。(正如 Little Bobby Tables 所指出的,这些天传递名称非常罕见,最好使用 lambda/closure。)

于 2010-05-23T07:26:20.373 回答
1

AFAIK,现代 Fortran 是通过引用传递的(保持与 ye olde FORTRAN 的兼容性)。

现代 Fortran 具有您期望的模块化语言的所有细节,因此您可以在其中构建良好的系统。没有人这样做,因为“Fortran 过时了”,每个人都想用 C# 编写代码,“因为它很酷。”。

于 2010-05-23T07:40:42.617 回答
-1

在 Java 中,所有对象都是通过引用传递的。

于 2010-05-23T08:26:15.287 回答