{"action":"created","issue":{"url":"https://api.github.com/repos/scala/scala/issues/6050","repository_url":"https://api.github.com/repos/scala/scala","labels_url":"https://api.github.com/repos/scala/scala/issues/6050/labels{/name}","comments_url":"https://api.github.com/repos/scala/scala/issues/6050/comments","events_url":"https://api.github.com/repos/scala/scala/issues/6050/events","html_url":"https://github.com/scala/scala/pull/6050","id":253680027,"number":6050,"title":"Implementation of byname implicits with recursive dictionaries.","user":{"login":"milessabin","id":131183,"avatar_url":"https://avatars3.githubusercontent.com/u/131183?v=4","gravatar_id":"","url":"https://api.github.com/users/milessabin","html_url":"https://github.com/milessabin","followers_url":"https://api.github.com/users/milessabin/followers","following_url":"https://api.github.com/users/milessabin/following{/other_user}","gists_url":"https://api.github.com/users/milessabin/gists{/gist_id}","starred_url":"https://api.github.com/users/milessabin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/milessabin/subscriptions","organizations_url":"https://api.github.com/users/milessabin/orgs","repos_url":"https://api.github.com/users/milessabin/repos","events_url":"https://api.github.com/users/milessabin/events{/privacy}","received_events_url":"https://api.github.com/users/milessabin/received_events","type":"User","site_admin":false},"labels":[{"id":216463557,"url":"https://api.github.com/repos/scala/scala/labels/release-notes","name":"release-notes","color":"d4c5f9","default":false}],"state":"open","locked":false,"assignee":{"login":"adriaanm","id":91083,"avatar_url":"https://avatars2.githubusercontent.com/u/91083?v=4","gravatar_id":"","url":"https://api.github.com/users/adriaanm","html_url":"https://github.com/adriaanm","followers_url":"https://api.github.com/users/adriaanm/followers","following_url":"https://api.github.com/users/adriaanm/following{/other_user}","gists_url":"https://api.github.com/users/adriaanm/gists{/gist_id}","starred_url":"https://api.github.com/users/adriaanm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriaanm/subscriptions","organizations_url":"https://api.github.com/users/adriaanm/orgs","repos_url":"https://api.github.com/users/adriaanm/repos","events_url":"https://api.github.com/users/adriaanm/events{/privacy}","received_events_url":"https://api.github.com/users/adriaanm/received_events","type":"User","site_admin":false},"assignees":[{"login":"adriaanm","id":91083,"avatar_url":"https://avatars2.githubusercontent.com/u/91083?v=4","gravatar_id":"","url":"https://api.github.com/users/adriaanm","html_url":"https://github.com/adriaanm","followers_url":"https://api.github.com/users/adriaanm/followers","following_url":"https://api.github.com/users/adriaanm/following{/other_user}","gists_url":"https://api.github.com/users/adriaanm/gists{/gist_id}","starred_url":"https://api.github.com/users/adriaanm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriaanm/subscriptions","organizations_url":"https://api.github.com/users/adriaanm/orgs","repos_url":"https://api.github.com/users/adriaanm/repos","events_url":"https://api.github.com/users/adriaanm/events{/privacy}","received_events_url":"https://api.github.com/users/adriaanm/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/scala/scala/milestones/66","html_url":"https://github.com/scala/scala/milestone/66","labels_url":"https://api.github.com/repos/scala/scala/milestones/66/labels","id":2719690,"number":66,"title":"2.13.0-M4","description":"This milestone is focused on settling the new collections API, and any fixes directly needed for that. Anything else should go to M5.\r\n","creator":{"login":"adriaanm","id":91083,"avatar_url":"https://avatars2.githubusercontent.com/u/91083?v=4","gravatar_id":"","url":"https://api.github.com/users/adriaanm","html_url":"https://github.com/adriaanm","followers_url":"https://api.github.com/users/adriaanm/followers","following_url":"https://api.github.com/users/adriaanm/following{/other_user}","gists_url":"https://api.github.com/users/adriaanm/gists{/gist_id}","starred_url":"https://api.github.com/users/adriaanm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriaanm/subscriptions","organizations_url":"https://api.github.com/users/adriaanm/orgs","repos_url":"https://api.github.com/users/adriaanm/repos","events_url":"https://api.github.com/users/adriaanm/events{/privacy}","received_events_url":"https://api.github.com/users/adriaanm/received_events","type":"User","site_admin":false},"open_issues":12,"closed_issues":106,"state":"open","created_at":"2017-08-23T23:45:35Z","updated_at":"2018-05-09T09:44:51Z","due_on":"2018-05-15T07:00:00Z","closed_at":null},"comments":39,"created_at":"2017-08-29T14:21:11Z","updated_at":"2018-05-09T09:45:07Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/scala/scala/pulls/6050","html_url":"https://github.com/scala/scala/pull/6050","diff_url":"https://github.com/scala/scala/pull/6050.diff","patch_url":"https://github.com/scala/scala/pull/6050.patch"},"body":"**This Typelevel Scala collaboration sponsored by Lightbend ...**\r\n\r\nThis is an implementation of byname implicit parameters with recursive dictionaries, intended as a language-level replacement for shapeless's `Lazy` type. As of this PR, implicit arguments can be marked as byname and at call sites recursive uses of implicit values are permitted if they occur in an implicit byname argument.\r\n\r\nThere is a SIP describing this language change in greater detail [here](http://docs.scala-lang.org/sips/byname-implicits.html).\r\n\r\nConsider the following example,\r\n\r\n```scala\r\ntrait Foo { def next: Foo }\r\nobject Foo {\r\n  implicit def foo(implicit rec: Foo): Foo = new Foo { def next = rec }\r\n}\r\nval foo = implicitly[Foo]\r\nassert(foo eq foo.next)\r\n```\r\nIn current Scala this would diverge due to the recursive implicit argument `rec` of method `foo`. Under the scheme implemented in this PR we can mark the recursive implicit parameter as byname,\r\n\r\n```scala\r\ntrait Foo { def next: Foo }\r\nobject Foo {\r\n  implicit def foo(implicit rec: => Foo): Foo = new Foo { def next = rec }\r\n                              // ^^\r\n}\r\nval foo = implicitly[Foo]\r\nassert(foo eq foo.next)\r\n```\r\nand recursive occurrences of this sort are extracted out as `val` members of a local synthetic object as follows,\r\n```scala\r\nval foo: Foo = scala.Predef.implicitly[Foo](\r\n  {\r\n    object LazyDefns$1 {\r\n      val rec$1: Foo = Foo.foo(rec$1)\r\n                       //      ^^^^^\r\n                       // recursive knot tied here\r\n    }\r\n    LazyDefns$1.rec$1\r\n  }\r\n)\r\nassert(foo eq foo.next)\r\n```\r\nThe example now compiles with the assertion successful. Note that the recursive use of `rec$1` occurs within the byname argument of `foo` and is consequently deferred. The desugaring matches what a programmer would do to construct such a recursive value explicitly.\r\n\r\nThis general pattern is essential to the derivation of type class instances for recursive data types, one of shapeless's most common applications. Byname implicits have a number of benefits over the macro implementation of `Lazy` in shapeless,\r\n\r\n+ the implementation of `Lazy` in shapeless is extremely delicate, relying on non-portable compiler internals. By contrast there is already an initial implementation of byname implicits in Dotty: lampepfl/dotty#1998.\r\n+ the shapeless implementation is unable to modify divergence checking, so to solve recursive instances it effectively disables divergence checking altogether ... this means that incautious use of `Lazy` can cause the typechecker to loop indefinitely. The byname implicits implementation is able to both solve recursive occurrences and check for divergence.\r\n+ the implementation of `Lazy` interferes with the heuristics for solving inductive implicits in #6481 because the latter depends on being able to verify that induction steps strictly reduce the size of the types being solved for; the additional `Lazy` type constructors make the type appear be non-decreasing in size. Whilst this could be special-cased, doing so would require some knowledge of shapeless to be incorporated into the compiler. Being a language-level feature, byname implicits can be accommodated directly in the induction heuristics.\r\n+ in common cases more implicit arguments would have to be marked as `Lazy` than would have to be marked as byname under this PR due to restrictions on what the `Lazy` macro is able to do. Given that there is a runtime cost associated with capturing the thunks required for both `Lazy` and byname arguments, any reduction in the number is beneficial."},"comment":{"url":"https://api.github.com/repos/scala/scala/issues/comments/387684534","html_url":"https://github.com/scala/scala/pull/6050#issuecomment-387684534","issue_url":"https://api.github.com/repos/scala/scala/issues/6050","id":387684534,"user":{"login":"adriaanm","id":91083,"avatar_url":"https://avatars2.githubusercontent.com/u/91083?v=4","gravatar_id":"","url":"https://api.github.com/users/adriaanm","html_url":"https://github.com/adriaanm","followers_url":"https://api.github.com/users/adriaanm/followers","following_url":"https://api.github.com/users/adriaanm/following{/other_user}","gists_url":"https://api.github.com/users/adriaanm/gists{/gist_id}","starred_url":"https://api.github.com/users/adriaanm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriaanm/subscriptions","organizations_url":"https://api.github.com/users/adriaanm/orgs","repos_url":"https://api.github.com/users/adriaanm/repos","events_url":"https://api.github.com/users/adriaanm/events{/privacy}","received_events_url":"https://api.github.com/users/adriaanm/received_events","type":"User","site_admin":false},"created_at":"2018-05-09T09:45:07Z","updated_at":"2018-05-09T09:45:07Z","author_association":"OWNER","body":"As discussed, we'll review in Berlin and give ourselves until M5 to refine."}}
{"actor":{"display_login":"adriaanm"}}