Re: Allow top-level "implicit class"es by folding them into containing package-object
Jason Zaugg <[email protected]> Wed, 07 Dec 2016 10:31:42 +0000
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAG3_yeUwRuX4wjKa9_bpx38UcCjRmyW0XbT_=9nShAY8MgnKzA@mail.gmail.com> |
--001a114049a689994805430f0769 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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 each > 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[Wrapp= ed, > 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 class > is implicit? The compiler has only the name of the file as an entry in th= e > enclosing package scope. It would have to look inside the file to find ou= t > 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 --=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. --001a114049a689994805430f0769 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed= , 7 Dec 2016 at 18:51 martin odersky <<a href=3D"mailto:[email protected]= m">[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quo= te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"= ><div dir=3D"ltr" class=3D"gmail_msg"><div class=3D"gmail_extra gmail_msg">= <div class=3D"gmail_quote gmail_msg">On Wed, Dec 7, 2016 at 5:28 AM, Jason = Zaugg <span dir=3D"ltr" class=3D"gmail_msg"><<a href=3D"mailto:jzaugg@gm= ail.com" class=3D"gmail_msg" target=3D"_blank">[email protected]</a>></sp= an> wrote:<br class=3D"gmail_msg"><blockquote class=3D"gmail_quote gmail_ms= g" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">= <div dir=3D"ltr" class=3D"gmail_msg"><p style=3D"font-size:small;margin:1.2= em 0px" class=3D"gmail_msg"></p><div class=3D"m_-4429256695741974100m_-1002= 852262469377768markdown-here-wrapper gmail_msg"><p style=3D"margin:1.2em 0p= x!important" class=3D"gmail_msg">Unfortunately we have a number of assumpti= ons in our toolchain (mostly driven by the requirement of separate+incremen= tal compilation), that each class file comes from a single source file. Pac= kage objects are modelled as an object with the name package, so like any o= ther object they must be defined within a single source file (by convention= , named <code style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Co= urier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;bo= rder:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-ra= dius:3px;display:inline" class=3D"gmail_msg">package.scala</code>.)</p><p s= tyle=3D"margin:1.2em 0px!important" class=3D"gmail_msg"><br class=3D"gmail_= msg">I believe instead that we should allow top level implicit classes and = treat it as though it introduced companion object of type <code style=3D"fo= nt-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0p= x 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,23= 4,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" = class=3D"gmail_msg">Function1[Wrapped, Wrapper]</code>. The companion itsel= f 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.15em;paddi= ng:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);backgro= und-color:rgb(248,248,248);border-radius:3px;display:inline" class=3D"gmail= _msg">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"gmail_msg">new Wrapper(wrapped)</code> in order to make later opt= imizations for implicit classes work as expected. We already do this for ca= lls to the companion apply methods of case classes.</p></div></div></blockq= uote><div class=3D"gmail_msg"><br class=3D"gmail_msg"></div></div></div></d= iv><div dir=3D"ltr" class=3D"gmail_msg"><div class=3D"gmail_extra gmail_msg= "><div class=3D"gmail_quote gmail_msg"><div class=3D"gmail_msg">But there&#= 39;s another problem: How do you figure out that a top-level class is impli= cit? The compiler has only the name of the file as an entry in the enclosin= g package scope. It would have to look inside the file to find out whether = it contained an implicit class. That would break all our assumptions about = separate compilation.</div></div></div></div></blockquote><div><br></div><d= iv>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:<br></div><div class=3D"markdown-here-wrapper" s= tyle=3D""><pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,C= ourier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code st= yle=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 r= gb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display= :inline;white-space:pre;overflow:auto;border-radius:3px;border:1px solid rg= b(204,204,204);padding:0.5em 0.7em;display: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">https://gist.github.com/retronym= /8ca8026f5b7eb981b53f5c8923d50f54</a>)</div><div><br></div><div>-jason</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 /> --001a114049a689994805430f0769--