Google Groups

Re: [SIP 18] New SIP: Modularizing language features

Jorge Ortiz Mar 18, 2012 6:44 AM
Posted in group: scala-sips
First of all: this is a tempest in a teacup. The cries of pain from "expert" Scala users that they are being unduly punished ring hollow. Presumably, expert users of Scala are competent users of their build system and can trivially add compiler flags to their heart's content.

Second: people claiming that structural types and existential types can only be used deliberately are mistaken.

It's quite easy for structural types to creep into a public API unintentionally, via type inference. This has happened several times in the standard library. For examples, see SI-879 ( and SI-4791 ( In fact, I'd go so far as to say that even if someone explicitly chose to use structural types in a file or project, having a type be inferred as structural would almost always be undesirable.

Likewise, types inferred as existential types are almost never what you want. While debugging foursquare's compilation times recently, I discovered the compiler was inferring a particularly nasty LUB as a very complicated existential type. To give you an idea of the magnitude of the problem, the textual representation of the inferred type was 225kb. Yes, kilobytes. To be fair to the compiler, the inheritance hierarchy involved is incredibly nasty, and the situation did call for a LUB. And to be fair to existential types, it was really all the LUB's fault. However, warning on inferred existential types would have given us a clue that the LUB was going haywire. Though, again, even if I explicitly chose to use existentials here, even then I would almost never want them inferred.

* * *

That said, I do have some concerns about the proposal as it stands.

a) Will warnings/errors be emitted for these features at use-site or at definition-site? In the current state of the world, Dynamic needs -Xexperimental in both places. This makes sense, as the potential unsafety occurs at use-site. I'm not sure about macros, but I would hope the same is true. Emitting warnings/errors only at definition-site would 

b) I welcome a more principled approach to enabling features that will inevitably live behind flags (macros, dynamic, CPS). However, the "import" syntax strikes me as a mistake. I like that it gives features very Googleable names (try searching for "_ <: T" or "T { def foo: Bar }"), but the new meaning of import is too disimilar from what import already means. I know its inspired by Python, but I think Python imports are sufficiently different from Scala imports (they're more about adding an entire library/feature than bringing specific identifiers into scope) that it doesn't make much sense. If language syntax must be used, the only alternative I can come up with is package declarations extending marker traits (e.g., "package foo extends language.dynamic"), but that's also not very satisfying (and sucks if you're not in a package... "package _root_"?).

c) While some of the features proposed to be put behind flags/imports are truly dangerous or experimental enough that they should be opted into, others are "advanced" features but fairly innocuous. As far as I know, higher-kinded types never hurt anyone.

In general, I feel this is better done as a compiler plugin or a style checker than as something baked into the language, at least for now. First, such a tool is needed anyway, regardless of whether this SIP is implemented or not. This SIP doesn't (and can't!) cover things that are truly dangerous (as others have pointed out: any2stringadd, primitive widening, auto-tupling, etc). The only way for those so inclined to eradicate these constructs from their code is via a configurable style checker. Second, people's opinions will naturally vary on which features they consider "dangerous" or "advanced" and which they consider mundane. Giving them the option of turning warnings or errors on or off for particular features will allow for flexibility, and will let a set of "best practices" to arise from the community. I appreciate Scala's willingness to remove features considered dangerous (many of the places where Scala improves over Java are known problems in Java, but they can't be fixed because doing so would break backwards compatibility), but I think such changes at the language-level should only happen once they have been validated as "best practices" by the community. The proposed SIP seems at once to both go too far (no one has gripes with higher-kinded types) and not far enough (many have gripes with any2stringadd).

Foursquare started a compiler plugin to try to address some of the issues that were haunting us. I've open sourced the publicly interesting bits here: The project is in a nascent stage, but I hope it will grow to include many more warnings and to be configurable by its users. I've also recently discovered that Matthew Farwell has a similar project here:

In summary: Things currently behind flags (dynamic, macros, CPS) should be kept behind flags (hopefully standardized) or behind new language syntax. Further restrictions should be implemented with a configurable tool first. Once "best practices" emerge in the community, their restriction at the language level can be proposed.


On Sun, Mar 18, 2012 at 2:48 AM, martin odersky <> wrote:
Here's a new SIP which proposes to put some new and existing advanced
language features under an import flag. I expect we'll have an
interesting discussion about this one.
So, please, fire away!

Here's the link to the SIP:


 -- Martin