The proposal is at least to put it behind a language feature flag. This is especially important in Scala (compared to Java) because of implicits. How do we jump-to-definition with something that is not even visible ?
To clarify, would you be proposing blocking this syntax as well?
val x = Foo()
import x._
I had not thought of it. Do you have a case where it would be a problem ? First that comes to mind is that it would not be simple for IDEs to auto-generate imports anywhere but at the top-level.
One place which this is used that comes to mind is if you want to limit the scope of implicits like:
import org.json4s.dsl._
Which, IIRC, is importing the members of an object, which is equivalent to the above.
Oh, and Akkaās graph building DSL also relies on a similar mechanism.
Clarifying note on the motivation for this line of questioning: Iām deeply opposed to this proposal, but Iād also like to avoid ripping into a strawman, so I want to make sure I understand the details of what youāre proposing
If you donāt know where it was from at all, not even which library, then you downgrade (by switching to an earlier branch that compiled) and
- If you have an IDE, ask the IDE
- if not, drop
: Nothing
on an instance of it and recompile
Now you know where itās from and you can go search the API to try to find where it went.
If you do know where it was from, just go search the new API docs like youād have had to if it said error: object Thing is not a member of package boromir
.
This elaborate scenario has a simple solution.
Personally, Iāve run into āhereās sample code but it doesnāt work because they elided the imports because theyāre too longā as an error way more than āthis worked great, but after an upgrade things went missing and you canāt find where they used to come from and that is critical to solving the problemā.
Anyway, anyone who wants to is already free to not import everything from each member of the Fellowship of the Ring. If youāre just after Sting, a frying pan, and a horn, Scala certainly doesnāt stop you from calling them out specifically.
Seriously: I believe that the majority of Scala files I have worked in (11 years, 7 of them full-time) have involved at least one wildcard import. Thatās not the kind of specialized feature that is well-suited to a language feature flagā¦
When macros are in the mix, wildcard imports canāt be reliably expanded at all by tooling.
The idea is to take advantage of the shift to Dotty to introduce this breaking change. It is mainly in reaction to implied/delegate/given imports, which also introduce a breaking change. A new proposal could be to require givens to be ānon-wildcardly importedā : assume there is a field myimplicit
in package foo
. Then,
import foo._
import given foo._
should be written instead as:
import foo.{_, myimplicit}
What do you think ?
I think itās a really good way to raise the effort of migration enough to keep people on Scala 2. At least based on what I understand from whatās been described here, itād be a deal-breaker for me.
To be fair, the idea that advancing a major version is now the opportunity to change everything did not originate from @rjolly. My understanding is that we should all stop worrying and love ScalaFix.
I get that wildcard imports are far too popular to be killed. But if this conversation will convince a few people to use them less, it was worth it talking about it.
It was implied earlier that implicits may not have a name, so they cannot be imported by name, and maybe that means we need to always import them via wildcards. That sounds pretty terrible to me - what if there are conflicts among some of the imported unnamed implicits. There must be a way to refer to them individually in imports. My understanding is that they do not need a name, because we can refer to them by the name of their type. In that case, we need a way to import an implicit by naming their type. Maybe by putting the type name in square brackets? Like:
**import x.y.z.{Thing, [NiceType]} **
// imports x.y.x.Thing and the implicit instance in x.y.z that has type NiceType.
By-type imports are already implemented, see https://dotty.epfl.ch/docs/reference/contextual/import-delegate.html . I thought it was overly complicated, but maybe it is the way to go. The part that bothers me is when used in normal imports (non implied/delegate/given):
import foo.{_: MyType}
It makes sense for fields and objects, but what about methods ? And types ? And classes ?
If you prefer not using IDE, just do not use it. If you prefer not using wildcard, just do not use it.
I donāt see why we need to take this away from users and enforce someās preference to everyone.