{"action":"opened","issue":{"url":"https://api.github.com/repos/lampepfl/dotty/issues/3005","repository_url":"https://api.github.com/repos/lampepfl/dotty","labels_url":"https://api.github.com/repos/lampepfl/dotty/issues/3005/labels{/name}","comments_url":"https://api.github.com/repos/lampepfl/dotty/issues/3005/comments","events_url":"https://api.github.com/repos/lampepfl/dotty/issues/3005/events","html_url":"https://github.com/lampepfl/dotty/issues/3005","id":251908933,"number":3005,"title":"Add support for lazy (explicit|implicit) parameters","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":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-08-22T10:22:19Z","updated_at":"2017-08-22T10:22:19Z","closed_at":null,"body":"#1998 makes implicit parameters consistent with explicit parameters by allowing implicit parameters to also be by-name. This change was motivated in Dotty (and work in progress on Scala 2) to support the same sort of type level programming use cases which are currently enabled by shapeless's `Lazy` type.\r\n\r\nHowever, the bynamity of a parameter prevents it from being stable which means that the following,\r\n```scala\r\ntrait Foo {\r\n  type Out\r\n  def out: Out\r\n}\r\n\r\nobject Test {\r\n  implicit def bar(implicit foo: => Foo): foo.Out = foo.out\r\n}\r\n```\r\ndoesn't compile (either in Dotty or Scala 2 with by-name implicit support) because the by-name argument `foo` is not stable,\r\n```\r\nlazy-implicits-7.scala:12: error: stable identifier required, but foo found.\r\n  implicit def bar(implicit foo: => Foo): foo.Out = foo.out\r\n                                          ^\r\none error found\r\n```\r\nThis pattern is very important in implicit-based type level programming, so this would be a disappointing limitation. By contrast, shapeless's `Lazy` captures the value in a stable context and hence supports the following with vanilla Scala 2,\r\n```scala\r\nimplicit def bar(implicit foo: Lazy[Foo]): foo.value.Out = foo.value.out\r\n```\r\nCurrently the following is a workaround with by-name implicits which compiles both on my Scala 2 branch and with Dotty,\r\n\r\n```scala\r\ntrait Foo {\r\n  type Out\r\n  def out: Out\r\n}\r\n\r\nobject Foo {\r\n  type Aux[Out0] = Foo { type Out = Out0 }\r\n}\r\n\r\nobject Test {\r\n  implicit def bar[T](implicit foo: => Foo.Aux[T]): T = foo.value\r\n}\r\n```\r\nie. we use the Aux pattern to avoid the need for a stable value. This is clumsy however, and the additional type parameter (which typically must be inferred) can make it hard to express methods which also require explicit type arguments.\r\n\r\nSo, whilst by name implicits get us close be being able to replace shapeless's `Lazy` macro, it's not quite there.\r\n\r\nIt was proposed in the discussion on #1998 to use the `lazy` modifier on method parameters to express by-need (ie. at most once) evaluation semantics. If such parameters could participate in stable paths (at least modulo the restrictions described [here](http://scala-lang.org/blog/2016/02/17/scaling-dot-soundness.html#plugging-the-loopholes) and the issues enumerated in the [Scala 2 ticket](https://github.com/scala/bug/issues/240)) then a `lazy implicit` parameter would more or less exactly replicate the semantics of shapeless's `Lazy`.\r\n\r\n"}}
{"actor":{"display_login":"milessabin"}}