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

发布于 2024-12-01 02:14:22 字数 1140 浏览 1 评论 0原文

我刚刚开始使用 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 中的更改完全破坏(请参阅< a href="https://issues.scala-lang.org/browse/SI-4662">https://issues.scala-lang.org/browse/SI-4662)。显然,对于这个最基本的 IO 接口根本没有进行回归测试,这是一个坏兆头。
  3. 类型擦除非常糟糕,我真的很想知道为什么在 Scala 中决定将其保留下来。是的,我知道 Java 具有类型擦除功能,并且 Scala 是构建在 JVM 上的,但最终需要添加显式可见的内容,例如清单、专门化注释等来解决类型擦除的问题真的很难闻……我最终感觉 Scala 设计者将意识到这一切的愚蠢之处,并被迫实现正确的泛型类型,此时他们将然后有很多废弃不需要的东西。

我的问题是:

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

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

在这种情况下,根本不需要 ignoreCasestopwords 上的类型注释,它们只是增加了不必要的冗长。

感谢参与 Scala 开发的人员的任何评论。

I'm just getting started with Scala. I've been using Python for research programming, and I'm converting a fairly large (~ 4000 line) Python program.

A few comments:

  1. It looks like the right time to get involved in Scala, as a lot of good stuff has been added to 2.8.
  2. On the other hand ... I wonder why Scala doesn't seem to have a decent IO package, and why this doesn't seem to be a priority. In most languages, IO is considered one of the most fundamental operations, and parts of the language are typically designed specifically so that IO works well. For example, the IO library in Python seems one of the oldest and most stable parts of the language (at least in its interface). Yet the comments from two years ago say things like "Source.fromFile() is a massive hack, wait till so-and-so finishes the new IO package" -- and I see no movement towards finishing this. Even worse is the fact that Source.fromFile().getLines() -- which, hack or not, is the generally advertised interface -- was entirely broken by changes made in 2.9.0.1 (see https://issues.scala-lang.org/browse/SI-4662). Evidently there is no regression testing at all for this most basic of IO interfaces, which is a bad sign.
  3. Type erasure sucks so incredibly badly that I really wonder why the decision was made in Scala to stick it in. Yes, I know that Java has type erasure, and Scala is built on the JVM, but the resulting need to add explicitly visible stuff like manifests, specialization annotations, etc. etc. to work around type erasure just smells really bad ... I sense ultimately that the Scala designers will realize the folly of all this, and be forced to implement proper generic typing, at which point they will then have a lot of unneeded cruft to deprecate.

My question is:

Are there plans to add type inference for function parameters with default arguments? It's getting a bit annoying to write stuff like this:

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

In this case, there's simply no need at all for the type annotations on ignoreCase and stopwords, and they just add unneeded verbosity.

Thanks for any comments from those involved in Scala development.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎言笑 2024-12-08 02:14:22
  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"))
    使用(来源)
    val 行 = source.getLines
    

    由于source是一个Iterator,一旦你使用它,它就消失了。这是一个巧合,您可以在调用 toString 后重用它,而不是内在保证。

  3. 类型擦除并没有那么糟糕。事实上,如果它有太多阻碍,那就是糟糕设计的标志——你不应该检查某物的类型是什么,而是调用它的方法并让自行处理。并不是说它有时不烦人,但也不是那么糟糕。唉,这是与 Java 无缝兼容的基本选择,而且是非常有意识地做出的。我不认为 Scala 能够走出困境。

    Ceylon 是承诺消除擦除并保持与 Java 兼容性的新语言之一。如果 Ceylon 做到了这一点,并且我坚定地站在怀疑者阵营中,那么 Scala 可能会效仿。

    此外,最近关于 Java 8 闭包的讨论表明了可能对擦除采取一些措施的可能性。如果事实证明这是真的,那么 Scala 也可以赚钱。

至于这个问题,我同意这些类型是可以推断的。然而,我不确定是否有人使用默认参数做某些事情——目前的优先事项在其他地方。

  1. Scala has had good stuff added for quite a while, but as it gains popularity it will get increasingly more stable. People who were around before 2.8 had much more leverage on modifying the language than people nowdays -- both because they represented a bigger percentage of users, and because the language was more flexible.

    Take, for instance, your issue with erasure. As a 2.0 user you'd have a way bigger chance of getting something done about it than you have now. In fact, the impact that would have in compatibility is pretty much a guarantee that it won't happen anymore, unless Java leads.

  2. You come from a scripting language. Scripting languages are very much concerned with I/O, because that's their butter and bread. For Scala, any serious I/O is simply relegated to Java libraries -- that's kind of the point of having Scala be compatible with Java, after all.

    Furthermore, your characterization of 4662 is, actually, completely wrong. It was not broken at all, though a change in behavior made arguably incorrect code work again. This is 4662 in a nutshell:

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

    Since source is an Iterator, it is gone once you use it. It was a coincidence that you could reuse it after calling toString on it, not an intrinsic guarantee.

  3. Type erasure is not so bad. In fact, it is a sign of bad design if it gets much in the way -- you are not supposed to check what the type of something is, but to call methods on it and let it handle itself. Not to say it isn't annoying at times, but not so badly. Alas, it is a fundamental choice in having seamlessly compatibility with Java, and it was very consciously made. I don't see Scala leading the way out of it.

    One of the new languages that promise to get rid of erasure, and maintain compatibility with Java, is Ceylon. If Ceylon manages that, and I'm firmly in the doubters camp, then Scala could follow.

    Also, on a recent discussion of closures for Java 8 indicated the possibility that something might be done about erasure. If that turns out to be true, then Scala could cash in as well.

As for the question, I agree that these types could be inferred. I'm not sure anyone is doing something with default parameters, however -- priorities for the moment lie elsewhere.

久隐师 2024-12-08 02:14:22
  1. 因为底层虚拟机抽象了对“外部”世界的任何访问,所以基本上可以选择要么附带编译代码,使 Scala 不独立于平台,要么使用诸如 java.io.File 完全损坏了。
    Java 7(仅仅 15 年之后)终于添加了一些可用的文件系统 API,据我所知,正在进行的 Scala IO 库已经将其作为目标。还有一点就是其他运行平台的支持。发布只有 JVM 实现的 Scala IO 库并不是一个好主意。基本上来说:几周前,Java 7 使得拥有一些像样的 IO 库成为可能。考虑到 Scala 在不久的将来不会放弃对 Java 6(和 5)的支持,因此不要指望标准库很快就会提供 IO。

  2. 你用错了。但是,如果您认为“Scala 设计师会意识到这种愚蠢”,请随意创建您自己的语言,这会让一切变得更好。具体化的泛型很难与更高级的类型相结合。如果我必须选择,我每次都会选择 HKT 而不是具体化仿制药。

啊啊..对了。这些事情不是你的问题。回答您的实际问题:

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

  1. Yes

  2. Because the underlying VM abstracts any access to the world "outside", there is basically the option to either ship with compiled code, making Scala not platform-independent or using things like java.io.File which is just utterly broken.
    Java 7 has (after only 15 years) finally added some usable file system API, which is already targeted as far as I know by the in-progress Scala IO library. Another point is the support of other runtime platforms. It isn't a good idea to release a Scala IO library which has only a JVM implementation. So basically: Having some decent IO library was made possible by Java 7 a few weeks ago. Considering that Scala will not drop support for Java 6 (and 5) in the near future, don't expect IO shipping with the standard library soon.

  3. You are using it wrong. But feel free to create your own language which does everything better if you think "Scala designers will realize the folly". Reified generics are hard to combine with higher-kinded types. And if I had to choose, I will take HKT over reified generics every time.

Ahhh .. right. These things aren't your questions. Answer to your actual question:

It could be done, but people like to keep the rules simple. So probably not.

不离久伴 2024-12-08 02:14:22

我没有足够的代表权力将其添加为评论,因此我必须添加为答案。另外,这对于评论来说太长了。

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

项目 = SI AND(摘要 ~“默认”AND 摘要 ~“值”)

  1. 无评论
  2. 无评论
  3. 正如其他人指出的那样,具体化(即不是类型擦除)使得更高级的泛型更难以实现。这里直接引用了 Piessens、Moors、Odersky 的“Generics of a Higher Kind”第 6.1 节。

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

针对 .NET 平台的语言中的类似扩展面临着
更艰巨的挑战,因为虚拟机具有更丰富的类型概念
从而强制执行更严格的不变量。不幸的是,该模型
类型不包括更高级的类型。这样,才能保证充分
与该平台上其他语言的通用性的互操作性,
具有类型构造函数多态性的语言的编译器必须采用
部分擦除,以及代码专门化,以便
构造由以下结果产生的类型的必要表示
应用于参数的抽象类型构造函数。

您可以查看该论文以解释为什么高级泛型很重要。尽管 Scala 2.8 显然没有在新的集合库中广泛使用它们,但到目前为止 我发现不可能在一个没有高级类型的子类型化优雅方式(与 Scalaz 非子类型设计相比,我发现后者非常复杂)。

Daniel C. Sobral 关于您在答案下面的评论,我认为构造函数违反了 SOLID 中的 D 原则。 Urban Vagabon,应该利用工厂来实现控制反转,即好莱坞原则。另请参阅 Gilad Bracha 的博客“构造函数被认为是有害的”。

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

I don't have enough rep power to add this as a comment, so I must add as an answer. Also this is too long for a comment.

Regarding the main question, I agree that the types of input parameters with default values could be inferred. I did the following query at their Scala issues tracker and didn't find an applicable feature request. So perhaps you could file one there.

project = SI AND (summary ~ "default" AND summary ~ "value")

  1. no comment
  2. no comment
  3. As others have pointed out, reification (i.e. not type erasure) makes higher-kinded generics more difficult to implement. Here is a direct quote from section 6.1 of "Generics of a Higher Kind", Piessens, Moors, Odersky.

Since Scala uses type erasure in the back-end, the extent of the
changes is limited to the type checker. Clearly, our extension thus
does not have any impact on the run-time characteristics of a program.
Ironically, as type erasure is at the root of other limitations in
Scala, it was an important benefit in implementing type constructor
polymorphism.

Similar extensions in languages that target the .NET platform face a
tougher challenge, as the virtual machine has a richer notion of types
and thus enforces stricter invariants. Unfortunately, the model of
types does not include higher-kinded types. Thus, to ensure full
interoperability with genericity in other languages on this platform,
compilers for languages with type constructor polymorphism must resort
to partial erasure, as well as code specialisation in order to
construct the necessary representations of types that result from
abstract type constructors being applied to arguments.

You can review that paper for an explanation of why higher-kinded generics are important. Although Scala 2.8 does not apparently use them extensively in their new collections library, so far I find it is impossible to implement my category theory library in a subtyped elegant manner without higher-kinds (contrast this with Scalaz non-subtyped design which I find to be extremely complex).

Daniel C. Sobral regarding your comment below your answer, I think it is the D principle in SOLID that is violated by constructors. Urban Vagabon, factories should be used to achieve inversion-of-control, a/k/a the Hollywood principle. See also Gilad Bracha's blog "Constructors Considered Harmful".

This is not intended to be the most complete or best answer, rather some partial thoughts which might add to this knowledge-base.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文