-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Motivation
Generic programming often exhibits scenarios where an implicit expansion would diverge, were it not for a lazy implicit value that "ties the knot". Current Shapeless has the Lazy pseudo-type to handle this using some tricky macro machinery. Following an idea of @milessabin it seems cleaner to put this in the language and tie it to by-name implicit parameters.
Status Quo
By-name implicit parameters are disallowed in Scala-2. They have been introduced recently in dotty, but without attaching special meaning to them.
Proposal
Modify implicit search as follows:
When searching for an implicit value of type T to provide an argument for a by-name parameter of type => T:
-
Create a new implicit value with a fresh name lv, which has the signature of the following definition:
implicit lazy val lv: TThe current implementation uses the prefix
$lazy_implicit$followed by a unique integer for lv. -
This lazy val is not immediately available as candidate for implicit search (making it immediately available would result in a looping implicit computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter.
-
If this implicit search succeeds with expression
E, andEcontains references to the lazy implicit value lv, replaceEby{ implicit lazy val lv: T = E; lv }Otherwise, return
Eunchanged.
Implementation Status
This proposal has been implemented in #1993. The test cases in that PR starting with
lazy-implicits-... . scala
show where the feature is useful. All these test cases would have given a diverging implicit expansion before the change.