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 &lt;<a href=3D"mailto:[email protected]" class=3D"">=
[email protected]</a>&gt;:</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"">&lt;<a href=3D"mailto:jzaug=
[email protected]" target=3D"_blank" class=3D"">[email protected]</a>&gt;</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"">&nbsp; - Martin</div><div class=3D"">&nbsp;</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 &lt;<a href=3D"mailto:[email protected]" target=
=3D"_blank" class=3D"">[email protected]</a><wbr class=3D"">&gt=
; 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&nbsp;be explicitly de=
clared inside another <font face=3D"courier new, monospace" class=3D"m_-100=
2852262469377768gmail_msg">object</font>&nbsp;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">&nbsp; </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&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 />

--Apple-Mail=_03D76E87-951B-4225-B3EE-7A25C30C15B0--