Re: Allow top-level "implicit class"es by folding them into containing package-object
Roland Kuhn <[email protected]> Wed, 7 Dec 2016 10:04:46 +0100
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <[email protected]> |
--Apple-Mail=_03D76E87-951B-4225-B3EE-7A25C30C15B0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 > 7 dec. 2016 kl. 09:51 skrev martin odersky <[email protected]>: >=20 >=20 >=20 > On Wed, Dec 7, 2016 at 5:28 AM, Jason Zaugg <[email protected] <mailto:jza= [email protected]>> wrote: >=20 > Unfortunately we have a number of assumptions in our toolchain (mostly dr= iven by the requirement of separate+incremental compilation), that each cla= ss file comes from a single source file. Package objects are modelled as an= object with the name package, so like any other object they must be define= d within a single source file (by convention, named package.scala.) >=20 >=20 > I believe instead that we should allow top level implicit classes and tre= at it as though it introduced companion object of type Function1[Wrapped, W= rapper]. The companion itself would be seen as an implicit. The call to Wra= pper.apply(wrapped) couId be translated to new Wrapper(wrapped) in order to= make later optimizations for implicit classes work as expected. We already= do this for calls to the companion apply methods of case classes. >=20 >=20 > But there's another problem: How do you figure out that a top-level class= is implicit? The compiler has only the name of the file as an entry in the= enclosing package scope. It would have to look inside the file to find out= whether it contained an implicit class. That would break all our assumptio= ns about separate compilation. Would it be thinkable to forego separate compilation? Source files whose tr= anslation has not been invalidated since the last run could just be rehydra= ted from their class files (assuming that this can be made quick enough) or= even kept in memory between runs. How close is this to what zinc does? Regards, Roland >=20 > - Martin > =20 >=20 > On Wed, 7 Dec 2016 at 13:26 Ryan Williams <[email protected] = <mailto:[email protected]>> wrote: > The requirement that implicit classes be explicitly declared inside anoth= er object gets in my way frequently and feels like it could be relaxed. >=20 > My typical library code looks like: >=20 > package foo.bar >=20 > object Baz { > implicit class Baz(=E2=80=A6) { =E2=80=A6 } > } >=20 > and corresponding calling code: >=20 > import foo.bar.Baz.Baz >=20 > One of the two Baz-layers is redundant. >=20 > Logically, i want my implicit classes to be considered to live inside the= ir nearest containing package object (in this case foo.bar), just like non-= implicit classes, but I can only declare a given package object once, so to= use it I have to put all classes in a package in the same file (in the pac= kage object), which is also suboptimal. >=20 > LMK if I'm missing something? Thanks! >=20 > --=20 > You received this message because you are subscribed to the Google Groups= "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to [email protected] <mailto:scala-languag= [email protected]>. > For more options, visit https://groups.google.com/d/optout <https://group= s.google.com/d/optout>. >=20 > --=20 > You received this message because you are subscribed to the Google Groups= "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to [email protected] <mailto:scala-languag= [email protected]>. > For more options, visit https://groups.google.com/d/optout <https://group= s.google.com/d/optout>. >=20 >=20 >=20 > --=20 >=20 > Martin Odersky > EPFL and Lightbend >=20 > --=20 > You received this message because you are subscribed to the Google Groups= "scala-language" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to [email protected] <mailto:scala-languag= [email protected]>. > For more options, visit https://groups.google.com/d/optout <https://group= s.google.com/d/optout>. --=20 You received this message because you are subscribed to the Google Groups "= scala-language" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected]. For more options, visit https://groups.google.com/d/optout. --Apple-Mail=_03D76E87-951B-4225-B3EE-7A25C30C15B0 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=UTF-8 <html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset= =3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s= pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di= v><blockquote type=3D"cite" class=3D""><div class=3D"">7 dec. 2016 kl. 09:5= 1 skrev martin odersky <<a href=3D"mailto:[email protected]" class=3D"">= [email protected]</a>>:</div><br class=3D"Apple-interchange-newline"><di= v class=3D""><div dir=3D"ltr" class=3D""><br class=3D""><div class=3D"gmail= _extra"><br class=3D""><div class=3D"gmail_quote">On Wed, Dec 7, 2016 at 5:= 28 AM, Jason Zaugg <span dir=3D"ltr" class=3D""><<a href=3D"mailto:jzaug= [email protected]" target=3D"_blank" class=3D"">[email protected]</a>></span> w= rote:<br class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0= .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr" class= =3D""><div style=3D"font-size: small; margin: 1.2em 0px;" class=3D""><br cl= ass=3D"webkit-block-placeholder"></div><div class=3D"m_-1002852262469377768= markdown-here-wrapper"><p style=3D"margin:1.2em 0px!important" class=3D"">U= nfortunately we have a number of assumptions in our toolchain (mostly drive= n by the requirement of separate+incremental compilation), that each class = file comes from a single source file. Package objects are modelled as an ob= ject with the name package, so like any other object they must be defined w= ithin a single source file (by convention, named <code style=3D"font-size:0= .85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;= padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);ba= ckground-color:rgb(248,248,248);border-radius:3px;display:inline" class=3D"= ">package.scala</code>.)</p><p style=3D"margin:1.2em 0px!important" class= =3D""><br class=3D"">I believe instead that we should allow top level impli= cit classes and treat it as though it introduced companion object of type <= code style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon= ospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px = solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;= display:inline" class=3D"">Function1[Wrapped, Wrapper]</code>. The companio= n itself would be seen as an implicit. The call to <code style=3D"font-size= :0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15e= m;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);= background-color:rgb(248,248,248);border-radius:3px;display:inline" class= =3D"">Wrapper.apply(wrapped)</code> couId be translated to <code style=3D"f= ont-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0= px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,2= 34,234);background-color:rgb(248,248,248);border-radius:3px;display:inline"= class=3D"">new Wrapper(wrapped)</code> in order to make later optimization= s for implicit classes work as expected. We already do this for calls to th= e companion apply methods of case classes.</p></div></div></blockquote><div= class=3D""><br class=3D""></div><div class=3D"">But there's another proble= m: How do you figure out that a top-level class is implicit? The compiler h= as only the name of the file as an entry in the enclosing package scope. It= would have to look inside the file to find out whether it contained an imp= licit class. That would break all our assumptions about separate compilatio= n.</div></div></div></div></div></blockquote><div><br class=3D""></div><div= >Would it be thinkable to forego separate compilation? Source files whose t= ranslation has not been invalidated since the last run could just be rehydr= ated from their class files (assuming that this can be made quick enough) o= r even kept in memory between runs. How close is this to what zinc does?</d= iv><div><br class=3D""></div><div>Regards,</div><div><br class=3D""></div><= div>Roland</div><div><br class=3D""></div><blockquote type=3D"cite" class= =3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra= "><div class=3D"gmail_quote"><div class=3D""><br class=3D""></div><div clas= s=3D""> - Martin</div><div class=3D""> </div><blockquote class= =3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd= ing-left:1ex"><div class=3D"HOEnZb"><div class=3D"h5"><br class=3D""><div c= lass=3D"gmail_quote"><div dir=3D"ltr" class=3D"">On Wed, 7 Dec 2016 at 13:2= 6 Ryan Williams <<a href=3D"mailto:[email protected]" target= =3D"_blank" class=3D"">[email protected]</a><wbr class=3D"">>= ; wrote:<br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"mar= gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr= " class=3D"m_-1002852262469377768gmail_msg"><div class=3D"m_-10028522624693= 77768gmail_msg">The requirement that implicit classes be explicitly de= clared inside another <font face=3D"courier new, monospace" class=3D"m_-100= 2852262469377768gmail_msg">object</font> gets in my way frequently and= feels like it could be relaxed.</div><div class=3D"m_-1002852262469377768g= mail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></div><div class=3D= "m_-1002852262469377768gmail_msg">My typical library code looks like:</div>= <div class=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-100285226246= 9377768gmail_msg"></div><div class=3D"m_-1002852262469377768gmail_msg m_-10= 02852262469377768m_-347598849498143007prettyprint" style=3D"background-colo= r:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-= width:1px;word-wrap:break-word"><code class=3D"m_-1002852262469377768gmail_= msg m_-1002852262469377768m_-347598849498143007prettyprint"><div class=3D"m= _-1002852262469377768gmail_msg m_-1002852262469377768m_-347598849498143007s= ubprettyprint"><span style=3D"color:#008" class=3D"m_-1002852262469377768m_= -347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">pack= age</span><span style=3D"" class=3D"m_-1002852262469377768m_-34759884949814= 3007styled-by-prettify m_-1002852262469377768gmail_msg"> foo</span><span st= yle=3D"color:#660" class=3D"m_-1002852262469377768m_-347598849498143007styl= ed-by-prettify m_-1002852262469377768gmail_msg">.</span><span style=3D"" cl= ass=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-100= 2852262469377768gmail_msg">bar<br class=3D"m_-1002852262469377768gmail_msg"= ><br class=3D"m_-1002852262469377768gmail_msg"></span><span style=3D"color:= #008" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettif= y m_-1002852262469377768gmail_msg">object</span><span style=3D"" class=3D"m= _-1002852262469377768m_-347598849498143007styled-by-prettify m_-10028522624= 69377768gmail_msg"> </span><span style=3D"color:#606" class=3D"m_-100285226= 2469377768m_-347598849498143007styled-by-prettify m_-1002852262469377768gma= il_msg">Baz</span><span style=3D"" class=3D"m_-1002852262469377768m_-347598= 849498143007styled-by-prettify m_-1002852262469377768gmail_msg"> </span><sp= an style=3D"color:#660" class=3D"m_-1002852262469377768m_-34759884949814300= 7styled-by-prettify m_-1002852262469377768gmail_msg">{</span><span style=3D= "" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m= _-1002852262469377768gmail_msg"><br class=3D"m_-1002852262469377768gmail_ms= g"> </span><span style=3D"color:#008" class=3D"m_-1002852262469377768= m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">im= plicit</span><span style=3D"" class=3D"m_-1002852262469377768m_-34759884949= 8143007styled-by-prettify m_-1002852262469377768gmail_msg"> </span><span st= yle=3D"color:#008" class=3D"m_-1002852262469377768m_-347598849498143007styl= ed-by-prettify m_-1002852262469377768gmail_msg">class</span><span style=3D"= " class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_= -1002852262469377768gmail_msg"> </span><span style=3D"color:#606" class=3D"= m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-1002852262= 469377768gmail_msg">Baz</span><span style=3D"color:#660" class=3D"m_-100285= 2262469377768m_-347598849498143007styled-by-prettify m_-1002852262469377768= gmail_msg">(=E2=80=A6)</span><span style=3D"" class=3D"m_-10028522624693777= 68m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">= </span><span style=3D"color:#660" class=3D"m_-1002852262469377768m_-347598= 849498143007styled-by-prettify m_-1002852262469377768gmail_msg">{</span><sp= an style=3D"" class=3D"m_-1002852262469377768m_-347598849498143007styled-by= -prettify m_-1002852262469377768gmail_msg"> </span><span style=3D"color:#66= 0" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m= _-1002852262469377768gmail_msg">=E2=80=A6</span><span style=3D"" class=3D"m= _-1002852262469377768m_-347598849498143007styled-by-prettify m_-10028522624= 69377768gmail_msg"> </span><span style=3D"color:#660" class=3D"m_-100285226= 2469377768m_-347598849498143007styled-by-prettify m_-1002852262469377768gma= il_msg">}</span><span style=3D"" class=3D"m_-1002852262469377768m_-34759884= 9498143007styled-by-prettify m_-1002852262469377768gmail_msg"><br class=3D"= m_-1002852262469377768gmail_msg"></span><span style=3D"color:#660" class=3D= "m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-100285226= 2469377768gmail_msg">}</span><span style=3D"" class=3D"m_-10028522624693777= 68m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">= <br class=3D"m_-1002852262469377768gmail_msg"></span></div></code></div><di= v class=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-100285226246937= 7768gmail_msg"></div><div class=3D"m_-1002852262469377768gmail_msg">and cor= responding calling code:</div><div class=3D"m_-1002852262469377768gmail_msg= "><br class=3D"m_-1002852262469377768gmail_msg"></div><div class=3D"m_-1002= 852262469377768gmail_msg m_-1002852262469377768m_-347598849498143007prettyp= rint" style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1= 87);border-style:solid;border-width:1px;word-wrap:break-word"><code class= =3D"m_-1002852262469377768gmail_msg m_-1002852262469377768m_-34759884949814= 3007prettyprint"><div class=3D"m_-1002852262469377768gmail_msg m_-100285226= 2469377768m_-347598849498143007subprettyprint"><span style=3D"color:#008" c= lass=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-10= 02852262469377768gmail_msg">import</span><span style=3D"" class=3D"m_-10028= 52262469377768m_-347598849498143007styled-by-prettify m_-100285226246937776= 8gmail_msg"> foo</span><span style=3D"color:#660" class=3D"m_-1002852262469= 377768m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_m= sg">.</span><span style=3D"" class=3D"m_-1002852262469377768m_-347598849498= 143007styled-by-prettify m_-1002852262469377768gmail_msg">bar</span><span s= tyle=3D"color:#660" class=3D"m_-1002852262469377768m_-347598849498143007sty= led-by-prettify m_-1002852262469377768gmail_msg">.</span><span style=3D"col= or:#606" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-pret= tify m_-1002852262469377768gmail_msg">Baz</span><span style=3D"color:#660" = class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-1= 002852262469377768gmail_msg">.</span><span style=3D"color:#606" class=3D"m_= -1002852262469377768m_-347598849498143007styled-by-prettify m_-100285226246= 9377768gmail_msg">Baz</span><span style=3D"" class=3D"m_-100285226246937776= 8m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg"><= br class=3D"m_-1002852262469377768gmail_msg"></span></div></code></div><div= class=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-1002852262469377= 768gmail_msg"></div><div class=3D"m_-1002852262469377768gmail_msg">One of t= he two <font face=3D"courier new, monospace" class=3D"m_-100285226246937776= 8gmail_msg">Baz</font>-layers is redundant.</div><div class=3D"m_-100285226= 2469377768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></div><d= iv class=3D"m_-1002852262469377768gmail_msg">Logically, i want my implicit = classes to be considered to live inside their nearest containing <font face= =3D"courier new, monospace" class=3D"m_-1002852262469377768gmail_msg">packa= ge object</font> (in this case <font face=3D"courier new, monospace" class= =3D"m_-1002852262469377768gmail_msg">foo.bar</font>), just like non-implici= t classes, but I can only declare a given <font face=3D"courier new, monosp= ace" class=3D"m_-1002852262469377768gmail_msg">package object</font> once, = so to use it I have to put all classes in a package in the same file (in th= e package object), which is also suboptimal.</div><div class=3D"m_-10028522= 62469377768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></div><= div class=3D"m_-1002852262469377768gmail_msg">LMK if I'm missing something?= Thanks!</div></div><div class=3D""><br class=3D"webkit-block-placeholder">= </div> -- <br class=3D"m_-1002852262469377768gmail_msg"> You received this message because you are subscribed to the Google Groups "= scala-language" group.<br class=3D"m_-1002852262469377768gmail_msg"> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" clas= s=3D"m_-1002852262469377768gmail_msg" target=3D"_blank">scala-language+unsu= bscribe@<wbr class=3D"">googlegroups.com</a>.<br class=3D"m_-10028522624693= 77768gmail_msg"> For more options, visit <a href=3D"https://groups.google.com/d/optout" clas= s=3D"m_-1002852262469377768gmail_msg" target=3D"_blank">https://groups.goog= le.com/d/<wbr class=3D"">optout</a>.<br class=3D"m_-1002852262469377768gmai= l_msg"> </blockquote></div><div class=3D""><br class=3D"webkit-block-placeholder"><= /div> -- <br class=3D""> You received this message because you are subscribed to the Google Groups "= scala-language" group.<br class=3D""> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" targ= et=3D"_blank" class=3D"">scala-language+unsubscribe@<wbr class=3D"">googleg= roups.com</a>.<br class=3D""> For more options, visit <a href=3D"https://groups.google.com/d/optout" targ= et=3D"_blank" class=3D"">https://groups.google.com/d/<wbr class=3D"">optout= </a>.<br class=3D""> </div></div></blockquote></div><br class=3D""><br clear=3D"all" class=3D"">= <div class=3D""><br class=3D""></div>-- <br class=3D""><div class=3D"gmail_= signature" data-smartmail=3D"gmail_signature"><br class=3D"">Martin Odersky= <br class=3D"">EPFL and Lightbend</div> </div></div><div class=3D""><br class=3D"webkit-block-placeholder"></div> -- <br class=3D""> You received this message because you are subscribed to the Google Groups "= scala-language" group.<br class=3D""> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" clas= s=3D"">[email protected]</a>.<br class=3D""> For more options, visit <a href=3D"https://groups.google.com/d/optout" clas= s=3D"">https://groups.google.com/d/optout</a>.<br class=3D""> </div></blockquote></div><br class=3D""></body></html> <p></p> -- <br /> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br /> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]">scal= [email protected]</a>.<br /> For more options, visit <a href=3D"https://groups.google.com/d/optout">http= s://groups.google.com/d/optout</a>.<br /> --Apple-Mail=_03D76E87-951B-4225-B3EE-7A25C30C15B0--