-
Notifications
You must be signed in to change notification settings - Fork 14
Narrow implicit scope #446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Could you sketch out the rules for the implicit scope you have in mind? If I understand what you're proposing correctly, this seems overly restrictive. The implicit scope of the type |
I agree with the sentiment to make it tractable to reason about where implicit values come from, but am not yet sure that reducing implicit scope is the best way to accomplish it. If this ticket were titled “Make implicit scope easier to reason about” would the solution still be to narrow implicit scope? What about making it easier to visualize implicit scope, through printing of an implicit scope graph maybe? Or the ability to interact with the scope at debug time and find objects available and their source? |
Can someone name a specific search location that is unnecessary? |
For example, the various subpackages that prefix any type that's part of the type of the implicit we're looking for? See the recursive computation of the parts of a type specified by http://www.scala-lang.org/files/archive/spec/2.12/07-implicits.html#implicit-parameters That's a lot of parts! :-) For the record, I don't have a concrete proposal, or I would be SIPping it ;-) |
Prefixes definitely seem like a candidate for pruning. I think most people are unaware that they form part of the implicit scope, and I think there are very few examples in the wild of this being directly exploited (cue someone finding an example of me doing this in shapeless ;-). |
Prefixes are probably safe to remove. I can't think of any case where it would be considerably more difficult to achieve the same result without them. Usually the required changes should be limited to moving code around. There is a possibility of having a corner case where you want the same implicits to be available in multiple scopes (so they are currently scoped in a prefix) but you cannot duplicate them because that would lead to ambiguities when the scopes overlap. This could possibly be solved by treating implicits from multiple paths as identical in certain cases (e.g. simple aliasing of objects). A more restrictive alternative would be to only consider type variables which have an explicit annotation that makes them part of an implicit scope. For |
Maybe we should widen the ticket beyond narrowing implicit scope to simplifying implicit search. See also scala/scala3#3421 |
I agree that package objects in prefixes would be a good candidate for removal. For other prefixes there might be surprises, though. E.g.
Seems reasonable, but the implicit |
In that particular example, it would still be in scope based on the rule that includes companion implicits of all base types of |
Ah yes, you are right. In that case, maybe we could experiment with dropping the prefix rule and find out how much breaks? |
We put implicits on package objects in the ensime api, to save boilerplate, but it shouldn't be too hard to refactor it into an import. It's probably a code smell anyway, because it breaks typeclass coherence. |
out of scope for Scala 2 |
or a good candidate for |
Don't include all parts of type of implicit value. Implicits are plenty magical in how they propagate, let's make it tractable to reason about where they come from, while supporting common use cases of companion objects supplying e.g. serializers for the type they accompany.
The text was updated successfully, but these errors were encountered: