Re: Allow top-level "implicit class"es by folding them into containing package-object
martin odersky <[email protected]> Wed, 7 Dec 2016 11:35:15 +0100
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAENVNkYR8dUVyDC2AiBzHjX30MgRDzuf=UqSQf7EkCPW7R3DKA@mail.gmail.com> |
--94eb2c07e998cacbaf05430f146f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wed, Dec 7, 2016 at 11:31 AM, Jason Zaugg <[email protected]> wrote: > > > On Wed, 7 Dec 2016 at 18:51 martin odersky <[email protected]> wrote: > >> On Wed, Dec 7, 2016 at 5:28 AM, Jason Zaugg <[email protected]> wrote: >> >> Unfortunately we have a number of assumptions in our toolchain (mostly >> driven by the requirement of separate+incremental compilation), that eac= h >> class 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 >> defined within a single source file (by convention, named package.scala.= ) >> >> >> I believe instead that we should allow top level implicit classes and >> treat it as though it introduced companion object of type Function1[Wrap= ped, >> Wrapper]. The companion itself would be seen as an implicit. The call to >> Wrapper.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= . >> >> >> But there's another problem: How do you figure out that a top-level clas= s >> is implicit? The compiler has only the name of the file as an entry in t= he >> enclosing package scope. It would have to look inside the file to find o= ut >> whether it contained an implicit class. That would break all our >> assumptions about separate compilation. >> > > Good point. To fit in with that constraint, we'd need some scheme to > encode the implicit modifier into the name of a some class. For instance, > we could do something like: > > implicit class RichString(val s: String) { > /*synthetic*/ class Implicit$ // added by the compiler > } > > =E2=80=8B > There is precedent for adding synthetic inner classes (e.g javac does to > add to the signatures of "access constructors": https://gist. > github.com/retronym/8ca8026f5b7eb981b53f5c8923d50f54) > > -jason > > -- > 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]. > For more options, visit https://groups.google.com/d/optout. > That's an interesting idea! I had not thought of that. That could indeed solve the problem. - Martin --=20 Martin Odersky EPFL and Lightbend --=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. --94eb2c07e998cacbaf05430f146f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo= te">On Wed, Dec 7, 2016 at 11:31 AM, Jason Zaugg <span dir=3D"ltr"><<a h= ref=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>><= /span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8= ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br><d= iv class=3D"gmail_quote"><span class=3D""><div dir=3D"ltr">On Wed, 7 Dec 20= 16 at 18:51 martin odersky <<a href=3D"mailto:[email protected]" target= =3D"_blank">[email protected]</a>> wrote:<br></div><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"m_-2117841693745383485gmail_msg"><div c= lass=3D"gmail_extra m_-2117841693745383485gmail_msg"><div class=3D"gmail_qu= ote m_-2117841693745383485gmail_msg">On Wed, Dec 7, 2016 at 5:28 AM, Jason = Zaugg <span dir=3D"ltr" class=3D"m_-2117841693745383485gmail_msg"><<a hr= ef=3D"mailto:[email protected]" class=3D"m_-2117841693745383485gmail_msg" ta= rget=3D"_blank">[email protected]</a>></span> wrote:<br class=3D"m_-21178= 41693745383485gmail_msg"><blockquote class=3D"gmail_quote m_-21178416937453= 83485gmail_msg" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;paddi= ng-left:1ex"><div dir=3D"ltr" class=3D"m_-2117841693745383485gmail_msg"><p = style=3D"font-size:small;margin:1.2em 0px" class=3D"m_-2117841693745383485g= mail_msg"></p><div class=3D"m_-2117841693745383485m_-4429256695741974100m_-= 1002852262469377768markdown-here-wrapper m_-2117841693745383485gmail_msg"><= p style=3D"margin:1.2em 0px!important" class=3D"m_-2117841693745383485gmail= _msg">Unfortunately we have a number of assumptions in our toolchain (mostl= y driven by the requirement of separate+incremental compilation), that each= class file comes from a single source file. Package objects are modelled a= s an object with the name package, so like any other object they must be de= fined within 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);background-color:rgb(248,248,248);border-radius:3px;display:inline" cl= ass=3D"m_-2117841693745383485gmail_msg">package.scala</code>.)</p><p style= =3D"margin:1.2em 0px!important" class=3D"m_-2117841693745383485gmail_msg"><= br class=3D"m_-2117841693745383485gmail_msg">I believe instead that we shou= ld allow top level implicit classes and treat it as though it introduced co= mpanion object of type <code style=3D"font-size:0.85em;font-family:Consolas= ,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-sp= ace:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248= ,248);border-radius:3px;display:inline" class=3D"m_-2117841693745383485gmai= l_msg">Function1[Wrapped, Wrapper]</code>. The companion itself would be se= en as an implicit. The call to <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);background-color:rgb= (248,248,248);border-radius:3px;display:inline" class=3D"m_-211784169374538= 3485gmail_msg">Wrapper.apply(wrapped)</code> couId be translated to <code s= tyle=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);background-color:rgb(248,248,248);border-radius:3px;displa= y:inline" class=3D"m_-2117841693745383485gmail_msg">new Wrapper(wrapped)</c= ode> in order to make later optimizations for implicit classes work as expe= cted. We already do this for calls to the companion apply methods of case c= lasses.</p></div></div></blockquote><div class=3D"m_-2117841693745383485gma= il_msg"><br class=3D"m_-2117841693745383485gmail_msg"></div></div></div></d= iv><div dir=3D"ltr" class=3D"m_-2117841693745383485gmail_msg"><div class=3D= "gmail_extra m_-2117841693745383485gmail_msg"><div class=3D"gmail_quote m_-= 2117841693745383485gmail_msg"><div class=3D"m_-2117841693745383485gmail_msg= ">But there's another problem: How do you figure out that a top-level c= lass 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 assum= ptions about separate compilation.</div></div></div></div></blockquote><div= ><br></div></span><div>Good point. To fit in with that constraint, we'd= need some scheme to encode the implicit modifier into the name of a some c= lass. For instance, we could do something like:<br></div><div class=3D"m_-2= 117841693745383485markdown-here-wrapper"><pre style=3D"font-size:0.85em;fon= t-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1= .2em;margin:1.2em 0px"><code style=3D"font-size:0.85em;font-family:Consolas= ,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-sp= ace:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248= ,248);border-radius:3px;display:inline;white-space:pre-wrap;overflow:auto;b= order-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;disp= lay:block!important">implicit class RichString(val s: String) { /*synthetic*/ class Implicit$ // added by the compiler } </code></pre><div title=3D"MDH:PGRpdj5gYGA8YnI+aW1wbGljaXQgY2xhc3MgUmljaFN0= cmluZyh2YWwgczogU3RyaW5nKSB7PGJy PiZuYnNwOyAmbmJzcDsvKnN5bnRoZXRpYyovIGNsYXNzIEltcGxpY2l0JCAvLyBhZGRlZCBieSB= 0 aGUgY29tcGlsZXI8L2Rpdj48ZGl2Pn08L2Rpdj48ZGl2PmBgYDwvZGl2Pg=3D=3D" style=3D"= height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;pad= ding:0;margin:0">=E2=80=8B</div></div><div></div><div>There is precedent fo= r adding synthetic inner classes (e.g javac does to add to the signatures o= f "access constructors":=C2=A0<a href=3D"https://gist.github.com/= retronym/8ca8026f5b7eb981b53f5c8923d50f54" target=3D"_blank">https://gist.<= wbr>github.com/retronym/<wbr>8ca8026f5b7eb981b53f5c8923d50f<wbr>54</a>)</di= v><span class=3D"HOEnZb"><font color=3D"#888888"><div><br></div><div>-jason= </div></font></span></div></div><div class=3D"HOEnZb"><div class=3D"h5"> <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]" targ= et=3D"_blank">scala-language+unsubscribe@<wbr>googlegroups.com</a>.<br> For more options, visit <a href=3D"https://groups.google.com/d/optout" targ= et=3D"_blank">https://groups.google.com/d/<wbr>optout</a>.<br> </div></div></blockquote></div><div class=3D"gmail_extra"><br></div>That= 9;s an interesting idea! I had not thought of that. That could indeed solve= the problem.</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail= _extra">=C2=A0- Martin<br clear=3D"all"><div><br></div>-- <br><div class=3D= "gmail_signature" data-smartmail=3D"gmail_signature"><br>Martin Odersky<br>= EPFL and Lightbend</div> </div></div> <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 /> --94eb2c07e998cacbaf05430f146f--