gpt4 book ai didi

scala - Scala REPL中的递归重载语义-JVM语言

转载 作者:行者123 更新时间:2023-12-04 05:05:48 25 4
gpt4 key购买 nike

使用Scala的命令行REPL:

def foo(x: Int): Unit = {}
def foo(x: String): Unit = {println(foo(2))}


error: type mismatch;
found: Int(2)
required: String

看来您无法在REPL中定义重载的递归方法。我以为这是Scala REPL中的一个错误,并将其归档,但它几乎立即被“wontfix”关闭:考虑到解释器的语义,我看不到任何支持这种方式的方法,因为这两个方法必须进行编译一起。”他建议将这些方法放在一个封闭的对象中。

是否有JVM语言实现或Scala专家可以解释原因?我可以看到,如果方法例如互相调用将是一个问题,但是在这种情况下?

或者,如果这是一个太大的问题,并且您认为我需要更多的先决知识,那么有人对语言实现的书籍或网站有很好的链接吗,尤其是在JVM上? (我了解John Rose的博客以及《 Programming Language Pragmatics ...》一书,仅此而已。:)

最佳答案

问题是由于这样的事实,解释器通常必须用给定的名称替换现有元素,而不是重载它们。例如,我将经常尝试进行一些实验,经常创建一个称为test的方法:

def test(x: Int) = x + x

再过一会儿,假设我正在运行一个不同的实验,并且创建了另一个名为 test的方法,该方法与第一个方法无关:
def test(ls: List[Int]) = (0 /: ls) { _ + _ }

这不是一个完全不现实的情况。实际上,这正是大多数人使用解释器的方式,常常甚至没有意识到。如果解释器任意决定将 test的两个版本都保留在范围内,则可能导致在使用test时造成混淆的语义差异。例如,我们可能调用 test,意外地传递了 Int而不是 List[Int](这不是世界上最不可能的事故):
test(1 :: Nil)  // => 1
test(2) // => 4 (expecting 2)

随着时间的流逝,解释器的根范围将被各种方法,字段等的各种版本所困扰。我倾向于一次将解释器开放几天,但是如果允许这样的重载,我们将被迫“当事情变得太困惑时,“经常刷新”解释器。

这不是JVM或Scala编译器的限制,而是有意的设计决策。如该错误中所述,如果您不在根作用域之内,则仍然可以重载。对我来说,将您的测试方法包含在类中似乎是最好的解决方案。

关于scala - Scala REPL中的递归重载语义-JVM语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/120702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com