scala 2.9:使用默认参数对函数参数进行类型推断的计划?

时间:2011-08-23 08:48:38

标签: scala parameters default-value type-inference type-erasure

我刚刚开始使用Scala。我一直在使用Python进行研究编程,而且我正在转换一个相当大的(~4000行)Python程序。

一些评论:

  1. 看起来是参与Scala的最佳时机,因为2.8中添加了很多好东西。
  2. 另一方面......我想知道为什么Scala似乎没有一个像样的IO包,为什么这似乎不是一个优先事项。在大多数语言中,IO被认为是最基本的操作之一,并且语言的一部分通常是专门设计的,因此IO运行良好。例如,Python中的IO库似乎是该语言中最古老,最稳定的部分之一(至少在其界面中)。然而,两年前的评论说“Source.fromFile()之类的东西是一个大规模的黑客攻击,等到新的IO包完成” - 我看到没有动作完成这个。更糟糕的是,Source.fromFile()。getLines() - 其中,黑客与否,是一般广告界面 - 由于2.9.0.1中的更改​​而被完全破坏(参见{ {3}})。显然,对于这个最基本的IO接口,根本没有回归测试,这是一个不好的迹象。
  3. 类型擦除非常糟糕,以至于我真的想知道为什么Scala决定坚持使用它。是的,我知道Java有类型擦除,而Scala是在JVM上构建的,但最终需要明确添加像清单,专业化注释等可见的东西,以解决类型擦除只是闻起来很糟糕...我最终感觉到Scala设计师将意识到所有这些的愚蠢,并被迫实施适当的通用类型,其中他们将有很多不必要的东西要弃用。
  4. 我的问题是:

    是否计划使用默认参数为函数参数添加类型推断?写这样的东西有点烦人:

      def add_words(words:Traversable[String], ignoreCase:Boolean=true,
                    stopwords:Set[String]=Set[String]()) {
        ...
      }
    

    在这种情况下,根本不需要 ignoreCase stopwords 上的类型注释,它们只是添加了不必要的详细程度。

    感谢参与Scala开发的人员的任何意见。

3 个答案:

答案 0 :(得分:5)

  1. Scala在很长一段时间内已经添加了很多东西,但随着它的普及,它会变得越来越稳定。 2.8之前的人比现在的人更容易修改语言 - 因为他们代表了更大比例的用户,并且因为语言更灵活。

    以你的擦除问题为例。作为一个2.0用户,你有比现在更大的机会完成任务。事实上,除非Java领先,否则兼容性的影响几乎可以保证它不再发生。

  2. 您来自脚本语言。脚本语言非常关注I / O,因为这是他们的黄油和面包。对于Scala来说,任何严肃的I / O都只是降级到Java库 - 毕竟,这就是让Scala与Java兼容的重点。

    此外,您对4662的描述实际上是完全错误的。虽然行为的改变可以说错误的代码再次起作用,但它并没有被所有打破。简而言之,这是4662:

    val source = scala.io.Source.fromFile(new java.io.File("test1.file"))
    use(source)
    val lines = source.getLines
    

    由于sourceIterator,因此一旦您使用它就会消失。巧合,您可以在调用toString之后重复使用它,而不是内在保证。

  3. 类型擦除并不是那么糟糕。事实上,它是一个糟糕的设计标志,如果它有很多阻碍 - 你不应该检查什么类型的东西,而是调用它上面的方法,并让处理自己。不是说它有时不烦人,但不是那么糟糕。唉,它是与Java无缝兼容的基本选择,而且它是非常有意识的。我没有看到Scala引领它。

    一种新的语言,它承诺摆脱擦除,并保持与Java的兼容性,是锡兰。如果锡兰能够做到这一点,而且我坚定地站在怀疑者阵营,那么Scala就可以效仿。

    此外,最近关于Java 8闭包的讨论表明可能会对擦除做些什么。如果事实证明是真的,那么Scala也可以兑现。

  4. 关于这个问题,我同意可以推断出这些类型。我不确定是否有人正在使用默认参数,但目前的优先级还在其他地方。

答案 1 :(得分:2)

  1. 因为底层VM抽象了对“外部”世界的任何访问,所以基本上可以选择运送已编译的代码,使Scala不依赖于平台或使用java.io.File之类的东西彻底破碎了。 Java 7(仅仅15年后)终于添加了一些可用的文件系统API,据我所知,正在进行的Scala IO库已经成为目标。另一点是其他运行时平台的支持。发布仅具有JVM实现的Scala IO库不是一个好主意。所以基本上:几周前Java 7就有了一些像样的IO库。考虑到Scala不会在不久的将来放弃对Java 6(和5)的支持,不要指望很快就会使用标准库运送IO。

  2. 你错了。但是如果您认为“Scala设计师会意识到愚蠢”,那么随意创建自己的语言可以做得更好。具体化的泛型很难与更高级的类型相结合。如果我不得不选择的话,我每次都会把HKT用于修改后的仿制药。

  3. 啊,对啊..对。这些都不是你的问题。回答你的实际问题:

    可以做到,但人们喜欢保持规则简单。所以可能不是。

答案 2 :(得分:0)

我没有足够的代表权来添加这个作为评论,所以我必须添加作为答案。这也是评论的时间太长了。

关于主要问题,我同意可以推断出具有默认值的输入参数类型。我在Scala issues tracker处进行了以下查询,但没有找到适用的功能请求。所以也许你可以在那里提出一个。

  

project = SI AND(summary~“default”AND summary~“value”)

  1. 没有评论
  2. 没有评论
  3. 正如其他人所指出的那样,具体化(即不是类型擦除)使得更高通用的泛型更难以实现。以下是“更高种类的仿制药”第6.1节的直接引用,Piessens,Moors,Odersky。
  4.   

    由于Scala在后端使用类型擦除,因此   更改仅限于类型检查器。显然,我们的延伸就这样了   对程序的运行时特性没有任何影响。   具有讽刺意味的是,类型擦除是其他限制的根源   Scala,它是实现类型构造函数的重要优势   多态性。

         

    面向.NET平台的语言中的类似扩展面临着一个问题   更严峻的挑战,因为虚拟机具有更丰富的类型概念   从而强制执行更严格的不变量。不幸的是,模型   类型不包括更高级的类型。因此,要确保充分   在这个平台上与其他语言的通用性互操作,   具有类型构造函数多态的语言的编译器必须求助   部分擦除,以及代码专业化   构造由此产生的类型的必要表示   抽象类型构造函数应用于参数。

    您可以查看该论文,以解释为什么更高级别的仿制药很重要。虽然Scala 2.8显然没有在他们的新集合库中广泛使用它们,但是到目前为止I find不可能在没有更高种类的情况下以子类优雅的方式实现我的类别理论库(与Scalaz非子类型设计形成鲜明对比)我觉得非常复杂。)

    Daniel C. Sobral关于你的回答的评论,我认为这是SOLID中的D原则被构造者违反。 Urban Vagabon,工厂应该用来实现倒置控制,a / k / a好莱坞原则。另见Gilad Bracha的博客“Constructors Considered Harmful”。

    这不是最完整或最好的答案,而是一些可能会增加这个知识库的部分想法。