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">&lt;<a h=
ref=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>&gt;<=
/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 &lt;<a href=3D"mailto:[email protected]" target=
=3D"_blank">[email protected]</a>&gt; 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">&lt;<a hr=
ef=3D"mailto:[email protected]" class=3D"m_-2117841693745383485gmail_msg" ta=
rget=3D"_blank">[email protected]</a>&gt;</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&#39;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&#39;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 &quot;access constructors&quot;:=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&quot; 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&#3=
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&quot; 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--