A missing replacement for Scala 2 implicits in Scala 3 #12007
Replies: 8 comments 3 replies
-
The recommended Scala 3 idiom for this would be to use implicit function types. You can write an implicit function lambda like this:
but it's type is an implicit function not a regular one. Nevertheless, I believe that adding more ways of defining an impllicit closure would be confusing. So if you want to define an implicit closure with regular function type you have to do it the long way:
But like I said, it's usually better to use |
Beta Was this translation helpful? Give feedback.
-
Moving to discussions |
Beta Was this translation helpful? Give feedback.
-
I think there are two potentially separate issues here: 1 Inconsistent use of class MyClass[A](using val x: Req[A]) { // compiles but why `using` keyword instead of `given`
summon[Req[A]]
}
I feel like this is very important since it is an inconsistency. I don't know how much this feature is used though. @odersky: Should I create a separate issue for this ? 2 Missing feature parity with Scala 2 in Scala 3 contextual abstractions Req.async[Future, Int] { implicit req => // how in Scala 3 ?
val r = summon[Req[A]]
assert(r eq req)
???
}
Pros: 1 Speed up death of Scala 2 implicits. This is heavily used in current Play framework Cons: 1 If context queries are adapted in some future of Scala, this feature will probably hardly be used. Req.async[Future, Int] { case req @ given Req[Int] => // compiles but very tedious
val r = summon[Req[A]]
assert(r eq req)
???
}
All in all, I think both these should be in Scala 3. |
Beta Was this translation helpful? Give feedback.
-
inline def implicitfn[T, U](inline f: T ?=> U): T => U = f(using _)
Req.async[Future, Int](implicitfn { req ?=>
val r = summon[Req[Int]]
assert(r eq req)
???
}) |
Beta Was this translation helpful? Give feedback.
-
The shortest I've come up with is:
|
Beta Was this translation helpful? Give feedback.
-
I also was surprised that both ZIO.runtime[Blocking].toManaged_.flatMap { implicit rt =>
// ...
} I think there should exist some more succinct way to support this feature rather than explicitly define given instance: rt =>
given zio.Runtime[Blocking] = rt
// ... |
Beta Was this translation helpful? Give feedback.
-
Scala 3 strives to be simple and regular. There are two kinds of function types: plain and contextual, and one kind of function literal for each type. Most libraries that encourage the use of |
Beta Was this translation helpful? Give feedback.
-
No: An implicit parameter of a method meant that the parameter was passed implicitly at the use site. But an implicit in a closure still produces a regular function that has to take an explicit argument. That's a glaring irregularity. It was sort of forced on us, since people felt they needed the use case, and we did not have context functions yet. It was also less visible in Scala 2 since you could pass a regular explicit argument for an implicit parameter. But with Scala-3's using clauses that's no longer possible. In summary, Scala 3 has a clear distinction between implicit and explicit, and is uniform for internal use and external API. This plays a crucial role in making implicits safer and more predictable. We will not complicate the syntax and muddle the waters by introducing cases that blur the distinction again.
Implicits will go away over time. Over the same timeframe libraries will hopefully migrate. Then you will be able to write Req.async[Future, Int] {
...
} which beats all the alternatives discussed so far by a huge margin. |
Beta Was this translation helpful? Give feedback.
-
Compiler version
Scala-3.0.0-RC1
Minimized code
Given the following code:
Scala 2
Scala 3:
Doesn't compile. No easy way to make req implicit.
Expectation
This should compile:
This is probably a stretch given
req
's type is not ascribed:Extra 1
Note that a version of this works in Scala 3 already:
Extra 2
However this version is probably not consistency with Scala 3 given.
using
is used to query implicits but here it is used to define an implicit. A better and more consistency keyword here isgiven
:Beta Was this translation helpful? Give feedback.
All reactions