-
Notifications
You must be signed in to change notification settings - Fork 19
Allow multiple implicit parameter blocks #8
Comments
I was drafting an email about this, with an intro and everything. I made some light editing, but here's the first part. This should not be news to Miles at least. Last year I gave a short talk at the Scala workshop on this, and last year I wrote a blog post about the idea. The goal is to support better use cases such as: def foo(a: Universe)(b: a.Tree): C => D Each foo caller needs to specify both a and b, even though passing b would be enough to deduce a. To avoid this problem, I proposed allowing implicit parameter lists at arbitrary positions: def foo[[a: Universe]](b: a.Tree): C => D This method could be invoked as foo(b), passing only b. In Typesafe Scala, this call syntax would be misunderstood as passing only a, because foo(a) and foo(a)(b) are supported. However, to pass a explicitly here you would have to write foo[a]: this way, it is easy to see whether a parameter list is implicit or explicit at the call site. For more details, I refer you to the above blog post. However, this is not yet detailed enough for a specification. Comments are welcome! In particular, adding this to a compiler fork creates additional compatibility problems. This extends which method signatures are valid with more syntactic sugar, so we need to figure out how Typesafe Scala and Typelevel Scala interoperate. We were last discussing that: (a) For Typelevel Scala, instead, we'd need to store extra information in the Scala-visible method signature. Either as additional info or as a separate attribute. (b) For Typesafe Scala, Miles proposed that an implicit parameter list not at the end of a method call should "erase" to a normal parameter list. So a library using the new feature would get essentially the same signatures as today (apart from the split into parameter lists). |
After the IRC discussion with @milessabin, I realized a potential issue with this proposal. With the current proposal, the syntax calling a method with such an extended signature depends on the Scala dialect you're using. There's no way to call such a method which is valid in both dialects. However, this only happens if you take advantage of the new syntax for defining the method! Example: //Typelevel-Scala definition:
def foo[[a: Universe]](b: a.Tree): C => D
//As seen by Typesafe-Scala:
def foo(a: Universe)(b: a.Tree): C => D
//At the call-site:
val a: Universe = ...
val b: a.Tree = ...
val c: C = ...
//Typelevel-Scala possible call sites
foo(b) //expands to:
foo[[a]](b)
//And has type : C => D
//But:
// foo(a)(b) //Rejected!
// foo(a)(b)(c) //Rejected!
// because that syntax is reserved for:
foo(b)(c) //Accepted :-)
//Typesafe-Scala possible call-sites:
foo(a)(b)
foo(a)(b)(c) The only workarounds I see are:
//Common subset:
foo_legacy(a)(b)
foo_legacy(a)(b)(c) Neither solution is really pretty, and I suspect trying to achieve source compatibility, or having these methods callable from Typesafe Scala, means looking for trouble. |
For the record, @milessabin answered on IRC: "We aren't maintaining source compatability, only binary." |
See also #14 on compatibility. |
Move to BlackboxContext
From @propensive's suggestion on #44, I realized we could encode implicitness using an annotation on the 1st parameter of the implicit parameter list. For internal consistency, we might want to add @implicit to (EDIT) standard parameter lists. Or maybe it doesn't help and we need to paper over the difference internally. This annotation should probably have the same caveats as code in |
Nice idea @propensive :-) |
Spec update for signature polymorphic methods
has anyone ever reported this with scala-lang and been assigned an SI- ticket for it? |
Not to my knowledge; I talked about this with Martin Odersky and he was skeptical. |
To resurrect this issue, please rework it as an issue/PR against Lightbend Scala (ie. scala/scala). |
there is a SIP at scala/docs.scala-lang#520 |
Miles:
The text was updated successfully, but these errors were encountered: