5

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.

Urban Vagabond
  • 7,282
  • 3
  • 28
  • 31
  • I don't see how the scala guys can fix type erasure because they don't own the VM. – Stilgar Aug 23 '11 at 10:09
  • @Stilgar they could probably pass Manifest-like information by default (which I think is what Gosu does and Kotlin will do) – Paolo Falabella Aug 23 '11 at 11:09
  • Although reified generics are slightly more convenient FOR THE DEVELOPER, than erasure, the issue is certainly not as bad as it seems. There are very good reasons for the JVM to use type erasure, which makes it more attractive environment, than for instance the .Net CLR. Check out [this link](http://olabini.com/blog/2010/07/questioning-the-reality-of-generics/) for more. – agilesteel Aug 23 '11 at 11:09
  • Yeah... the good reasons are that they wanted to implement generics fast and make everything work on compiler level so VMs written for various devices would still be supported. The link is an article written by dynamic language developer who is lazy. For a static language like Scala AND Java type erasure sucks. We agree Java is the most important language on the JVM, don't we? Not JRuby. I am pretty sure generics will be fixed at some point in the future and in fact Mark Reinhold has said so several times but it will take time. Not in Java 8 for sure. – Stilgar Aug 23 '11 at 11:17
  • @Stilgar: So can you actually present a type system with reified generics and higher-kinded types? Without that, the argument "type erasure sucks" is pretty moot, because there is nothing better to replace it at the moment. – soc Aug 23 '11 at 12:53
  • @soc reified generics (.NET style) are much better for a language like Java which still is the most important language on the JVM. I must admit I don't know enough about higher-kinded types but I know that type erasure hurts the Java language. I also hear complains from the Scala community in favour of reified generics so I assume they are a problem in Scala too. – Stilgar Aug 23 '11 at 14:06
  • @Stilgar: Generics in Scala work much better than generics in Java. Still, type erasure is annoying in both languages. But considering that Microsoft basically killed the language ecosystem around the CLR with the introduction of reified generics (even their own languages like F# have to duplicate huge amounts of code) because it is basically C#'s way or the high-way, I don't see any solution currently. Maybe someone comes up with a type system which can encode the relevant properties, but until now no one has presented that. – soc Aug 24 '11 at 10:56
  • Conclusion: While reified generics might be nice for languages with primitive typesystems (currently only C# and C++ use that technique) it is not a solution to the real-world problems. Scala can live with HKTs and type erasure, but it can't live with no HKT and reified generics. So if you have a solution, I would be glad to hear it. "Just adding" refied generics doesn't work. – soc Aug 24 '11 at 10:58

3 Answers3

5
  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.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Hi, sorry about responding late. I'm really surprised you think that the only problem with type erasure is that you can't check the type of something. Type erasure, at least in Java, means that if you have e.g. a List[T], you can't even create a new T object! And "checking the type" is in fact a normal Scala idiom with match. Look at the Hadoop API -- you need these ugly setFooClass(), setBarClass(), setBazClass() calls everywhere precisely to get around the fact that you can't create a new T given a Foo[T]. – Urban Vagabond Sep 04 '11 at 00:47
  • @Urban I don't think instantiating a T is a good idea to begin with. Factories are the proper way to do that, and you can pass factories around. In fact, even `Manifest` is a factory, of sorts. – Daniel C. Sobral Sep 04 '11 at 01:29
  • Why not? Factories are only the "proper" way to do that because type erasure forces you to do this. Also, as I said, using 'match' is one of the accepted Scala idioms. The Scala2e book gives lots of arguments why it isn't always the best way to be forced to implement everything using methods defined on classes. – Urban Vagabond Sep 04 '11 at 02:27
  • 1
    @Urban To put it simply, it violates the I part of SOLID principles. You can look up SOLID principles and you'll find lots of information. – Daniel C. Sobral Sep 04 '11 at 23:35
2
  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.

soc
  • 27,983
  • 20
  • 111
  • 215
  • 1
    Saying "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" is not very friendly. It was a valid question and probably in minds of most people coming from Scripting background. – Salil Aug 24 '11 at 07:03
  • Salil: I didn't intend to sound harsh. Considering that pretty much every scripting language is untyped I don't understand your last sentence. Care to elaborate? – soc Aug 24 '11 at 11:01
  • most of the people who are new to Java world, be it Scripting or C++/C#, do not appreciate 'type erasure'. It results into special cases while type checking and in Scala case statements also. Manifests themselves are a way to circumvent the limitations of type erasure. 'Urban Vagabond' raised a valid point about why Scala decided to continue the same 'mistake' Java did. Your reply along the line of 'go, create your own language' sounded unduly harsh. – Salil Aug 24 '11 at 12:10
  • I think we pretty much agree. I think everyone has understood the negative aspects of type erasure. But it is just not a solution to say "just fix it" without mentioning how. That's why I really would like to see a working solution, instead of pointing out the obvious. – soc Aug 24 '11 at 12:19
  • You really shouldn't respond with snippy comments on StackOverflow, keep them to yourself or assert your dominance over n00bs on scala-user – ThaDon Sep 25 '11 at 15:30
0

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.

Community
  • 1
  • 1
Shelby Moore III
  • 6,063
  • 1
  • 33
  • 36