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
Order of implicit arguments matters, so turning an implicit parameter into a context bound breaks implicit resolution #7054
Comments
Imported From: https://issues.scala-lang.org/browse/SI-7054?orig=1 |
Barnabás Králik (kralikba) said: What are Your comments on this? Does it have concrete causes that the context bounds are desugared into implicits that are at the beginning of the implicit parameter list? If not, this small change would make code clearer. |
@Blaisorblade said: This change might cause regressions when the opposite order is better, so it's not obvious it is an improvement. But I know no concrete instance, so there might be some non-obvious reason this regression is impossible. In fact, context bounds are always desugared to implicit params with a single type parameter ( Failing that, I don't see how this can be easily improved. |
@Blaisorblade said: |
Barnabás Králik (kralikba) said (edited on May 1, 2014 6:30:26 PM UTC): The problem - as I see it - is not the inference of itself the implicit, but the inference of the type parameter of a context bound. As far as I have understood, the context bound places a restriction on the type parameter - whereas implicit parameters might help in actually inferring a type parameter. Suppose the following: class A[X,Y]
class B; class C
implicit val a = new A[B,C]
def f[U,V : Manifest](u : U)(implicit ax : A[U,V]) = ... The intention of the programmer would be: get me a However, the signature of f tells the type inference engine that: The algorithm here chooses Nothing as the smallest type for which a Manifest exists; but One would need to write: def f[U,V](u : U)(implicit ax : A[U,V], m : Manifest[V]) = ... to let both implicits be correctly guessed. I would argue that something called a "bound" should not make the type inference engine make any guess about the type and then keep to it. Imagine if an upper type bound would make type inference assume that if the type parameter is not explicitly specified, then it must be itself the upper bound. |
@retronym said: |
@Blaisorblade said (edited on May 2, 2014 9:44:41 AM UTC):
The problem is that they help "too much" — indeed, also implicit parameters should simply be constraints. |
Barnabás Králik (kralikba) said: bq. the problem is that making it more predictable bq. (AFAIK) a hard research problem bq. Moreover, it would probably change behavior in some cases, so it would be hard to push this in for Scala 2. What comes to my mind are cases where implicits are explicitly passed; the order of parameters matters here a lot and mixing them up might sometimes cause bugs only detected at run time. Maybe a less intrusive patch that should not break existing code and not result in the complete rewrite of the inference algorithms could be proposed along the lines of the following:
|
@retronym said: |
@Blaisorblade said (edited on May 2, 2014 12:19:08 PM UTC):
Take an arbitrary Scala program requiring type/implicit inference to fill in some blanks. Can you predict whether Scalac will manage to do such inference? I know nobody who can. There are many other questions whose answer should be predictable and isn't. For instance, Dunfield and Krishnaswami write, in a type inference paper for a different language (without subtyping): For instance, imagine the statement "if you change the order of implicit parameters in a function declaration, it will still be possible to infer implicit parameters for every call site where it was possible before". If this were a theorem for Scala type inference, this bug would not show up. That's why I titled the bug "Order of implicit arguments matters". However, that paper contains a 70-page appendix of proofs, and the Scala type system is bigger and more complex, so it's not easy to extend their work to Scala — it would be another research effort. So, I don't have "specific ongoing research in mind", but maybe this research is happening as part of the Dotty project. But I would expect quite some improvements to be possible. |
@Blaisorblade said: Jason, does it make sense to close this as Won't Fix for Scala 2, since nobody plans to rewrite Scalac inference algorithm? |
@retronym said: Given that context bounds are a convenience feature only, and writing the implicit arguments offers a workaround when full control is needed, I do think this is a wont-fix. |
Below I show two lines of code which should be equivalent but aren't - implicit resolution has issues on the first. The workaround was simply to desugar the context bound
That: Man
into an implicit parameter - hence I would say that this is a bug.-Xprint:typer
suggest that this bug will stay open for long, as explained below.Non-working version:
Working version:
Note that the two lines desugar into different things: the order of implicit parameters is different.
The first desugars to:
Note that
That
is deduced from the last parameter and used before.The second example desugars to:
Complete example and error message below.
The error message mentions
Nothing
, as if type inference hadn't fully happened. In fact, this code would require the different implicits to be in different parameter lists - or failing that, scalac should do type inference across a single parameter list, the kind of thing which it consciously refuses to do for e.g. non-curried fold methods. Given that the second thing is not going to happen soon, I'd mention again my proposal for multiple implicit parameter lists:http://blaisorbladeprog.blogspot.de/2013/01/flexible-implicits-from-agda-for-scala.html
Note that if instead of a generic
Man
I useManifest
(as I was doing before reducing the example), the error message is completely different - it claims another implicit is missing, of typeCanBuild1[Int,That]
- as ifThat
hadn't yet been deduced.Scalac's lament:
The text was updated successfully, but these errors were encountered: