Re: Allow top-level "implicit class"es by folding them into containing package-object

martin odersky <[email protected]> Wed, 7 Dec 2016 09:51:09 +0100
Newsgroups gmane.comp.lang.scala
Message-ID <CAENVNkarOD8bCndfs9WiwMKfMwAfoOAEvcfETpdgwDaxMz80cA@mail.gmail.com>
--001a1148affa81d80c05430da06e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

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 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
assumptions about separate compilation.

  - Martin


>
> On Wed, 7 Dec 2016 at 13:26 Ryan Williams <[email protected]>
> wrote:
>
>> The requirement that implicit classes be explicitly declared inside
>> another object gets in my way frequently and feels like it could be
>> relaxed.
>>
>> My typical library code looks like:
>>
>> package foo.bar
>>
>> object Baz {
>>   implicit class Baz(=E2=80=A6) { =E2=80=A6 }
>> }
>>
>> and corresponding calling code:
>>
>> import foo.bar.Baz.Baz
>>
>> One of the two Baz-layers is redundant.
>>
>> Logically, i want my implicit classes to be considered to live inside
>> their 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 fi=
le
>> (in the package object), which is also suboptimal.
>>
>> LMK if I'm missing something? Thanks!
>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "scala-language" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> 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.
>



--=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.

--001a1148affa81d80c05430da06e
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 5:28 AM, Jason Zaugg <span dir=3D"ltr">&lt;<a hr=
ef=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 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><p style=3D=
"font-size:small;margin:1.2em 0px"></p><div class=3D"m_-1002852262469377768=
markdown-here-wrapper"><p style=3D"margin:1.2em 0px!important">Unfortunatel=
y we have a number of assumptions in our toolchain (mostly driven by the re=
quirement of separate+incremental compilation), that each class file comes =
from a single source file. Package objects are modelled as an object with t=
he name package, so like any other object they must be defined within a sin=
gle 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-co=
lor:rgb(248,248,248);border-radius:3px;display:inline">package.scala</code>=
.)</p><p style=3D"margin:1.2em 0px!important"><br>I believe instead that we=
 should allow top level implicit classes and treat it as though it introduc=
ed companion object of type <code style=3D"font-size:0.85em;font-family:Con=
solas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;whi=
te-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(24=
8,248,248);border-radius:3px;display:inline">Function1[Wrapped, Wrapper]</c=
ode>. The companion itself would be seen as an implicit. The call to <code =
style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospac=
e;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;displ=
ay:inline">Wrapper.apply(wrapped)</code> couId be translated to <code style=
=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;mar=
gin: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:in=
line">new Wrapper(wrapped)</code> in order to make later optimizations for =
implicit classes work as expected. We already do this for calls to the comp=
anion apply methods of case classes.</p></div></div></blockquote><div><br><=
/div><div>But there&#39;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 o=
ur assumptions about separate compilation.</div><div><br></div><div>=C2=A0 =
- Martin</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D=
"HOEnZb"><div class=3D"h5"><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Wed, 7 Dec 2016 at 13:26 Ryan Williams &lt;<a href=3D"mailto:ryan.blake.=
[email protected]" target=3D"_blank">[email protected]</a><wbr=
>&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_-1002852262469377768gmail_msg"><div class=3D"m_-1002852262469377768gm=
ail_msg">The requirement that implicit classes=C2=A0be explicitly declared =
inside another <font face=3D"courier new, monospace" class=3D"m_-1002852262=
469377768gmail_msg">object</font>=C2=A0gets in my way frequently and feels =
like it could be relaxed.</div><div class=3D"m_-1002852262469377768gmail_ms=
g"><br class=3D"m_-1002852262469377768gmail_msg"></div><div class=3D"m_-100=
2852262469377768gmail_msg">My typical library code looks like:</div><div cl=
ass=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-1002852262469377768=
gmail_msg"></div><div class=3D"m_-1002852262469377768m_-347598849498143007p=
rettyprint m_-1002852262469377768gmail_msg" style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px;word-wrap:break-word"><code class=3D"m_-1002852262469377768m_-3475988494=
98143007prettyprint m_-1002852262469377768gmail_msg"><div class=3D"m_-10028=
52262469377768m_-347598849498143007subprettyprint m_-1002852262469377768gma=
il_msg"><span style=3D"color:#008" class=3D"m_-1002852262469377768m_-347598=
849498143007styled-by-prettify m_-1002852262469377768gmail_msg">package</sp=
an><span style=3D"color:#000" class=3D"m_-1002852262469377768m_-34759884949=
8143007styled-by-prettify m_-1002852262469377768gmail_msg"> foo</span><span=
 style=3D"color:#660" class=3D"m_-1002852262469377768m_-347598849498143007s=
tyled-by-prettify m_-1002852262469377768gmail_msg">.</span><span style=3D"c=
olor:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-pr=
ettify m_-1002852262469377768gmail_msg">bar<br class=3D"m_-1002852262469377=
768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></span><span st=
yle=3D"color:#008" class=3D"m_-1002852262469377768m_-347598849498143007styl=
ed-by-prettify m_-1002852262469377768gmail_msg">object</span><span style=3D=
"color:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-=
prettify m_-1002852262469377768gmail_msg"> </span><span style=3D"color:#606=
" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_=
-1002852262469377768gmail_msg">Baz</span><span style=3D"color:#000" class=
=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-100285=
2262469377768gmail_msg"> </span><span style=3D"color:#660" class=3D"m_-1002=
852262469377768m_-347598849498143007styled-by-prettify m_-10028522624693777=
68gmail_msg">{</span><span style=3D"color:#000" class=3D"m_-100285226246937=
7768m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg=
"><br class=3D"m_-1002852262469377768gmail_msg">=C2=A0 </span><span style=
=3D"color:#008" class=3D"m_-1002852262469377768m_-347598849498143007styled-=
by-prettify m_-1002852262469377768gmail_msg">implicit</span><span style=3D"=
color:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-p=
rettify m_-1002852262469377768gmail_msg"> </span><span style=3D"color:#008"=
 class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-=
1002852262469377768gmail_msg">class</span><span style=3D"color:#000" class=
=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-100285=
2262469377768gmail_msg"> </span><span style=3D"color:#606" class=3D"m_-1002=
852262469377768m_-347598849498143007styled-by-prettify m_-10028522624693777=
68gmail_msg">Baz</span><span style=3D"color:#660" class=3D"m_-1002852262469=
377768m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_m=
sg">(=E2=80=A6)</span><span style=3D"color:#000" class=3D"m_-10028522624693=
77768m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_ms=
g"> </span><span style=3D"color:#660" class=3D"m_-1002852262469377768m_-347=
598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">{</span>=
<span style=3D"color:#000" class=3D"m_-1002852262469377768m_-34759884949814=
3007styled-by-prettify m_-1002852262469377768gmail_msg"> </span><span style=
=3D"color:#660" class=3D"m_-1002852262469377768m_-347598849498143007styled-=
by-prettify m_-1002852262469377768gmail_msg">=E2=80=A6</span><span style=3D=
"color:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-=
prettify m_-1002852262469377768gmail_msg"> </span><span style=3D"color:#660=
" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_=
-1002852262469377768gmail_msg">}</span><span style=3D"color:#000" class=3D"=
m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-1002852262=
469377768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></span><s=
pan style=3D"color:#660" class=3D"m_-1002852262469377768m_-3475988494981430=
07styled-by-prettify m_-1002852262469377768gmail_msg">}</span><span style=
=3D"color:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled-=
by-prettify m_-1002852262469377768gmail_msg"><br class=3D"m_-10028522624693=
77768gmail_msg"></span></div></code></div><div class=3D"m_-1002852262469377=
768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></div><div clas=
s=3D"m_-1002852262469377768gmail_msg">and corresponding calling code:</div>=
<div class=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-100285226246=
9377768gmail_msg"></div><div class=3D"m_-1002852262469377768m_-347598849498=
143007prettyprint m_-1002852262469377768gmail_msg" 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_-1002852262469377768m_-347=
598849498143007prettyprint m_-1002852262469377768gmail_msg"><div class=3D"m=
_-1002852262469377768m_-347598849498143007subprettyprint m_-100285226246937=
7768gmail_msg"><span style=3D"color:#008" class=3D"m_-1002852262469377768m_=
-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg">impo=
rt</span><span style=3D"color:#000" class=3D"m_-1002852262469377768m_-34759=
8849498143007styled-by-prettify m_-1002852262469377768gmail_msg"> foo</span=
><span style=3D"color:#660" class=3D"m_-1002852262469377768m_-3475988494981=
43007styled-by-prettify m_-1002852262469377768gmail_msg">.</span><span styl=
e=3D"color:#000" class=3D"m_-1002852262469377768m_-347598849498143007styled=
-by-prettify m_-1002852262469377768gmail_msg">bar</span><span style=3D"colo=
r:#660" class=3D"m_-1002852262469377768m_-347598849498143007styled-by-prett=
ify m_-1002852262469377768gmail_msg">.</span><span style=3D"color:#606" cla=
ss=3D"m_-1002852262469377768m_-347598849498143007styled-by-prettify m_-1002=
852262469377768gmail_msg">Baz</span><span style=3D"color:#660" class=3D"m_-=
1002852262469377768m_-347598849498143007styled-by-prettify m_-1002852262469=
377768gmail_msg">.</span><span style=3D"color:#606" class=3D"m_-10028522624=
69377768m_-347598849498143007styled-by-prettify m_-1002852262469377768gmail=
_msg">Baz</span><span style=3D"color:#000" class=3D"m_-1002852262469377768m=
_-347598849498143007styled-by-prettify m_-1002852262469377768gmail_msg"><br=
 class=3D"m_-1002852262469377768gmail_msg"></span></div></code></div><div c=
lass=3D"m_-1002852262469377768gmail_msg"><br class=3D"m_-100285226246937776=
8gmail_msg"></div><div class=3D"m_-1002852262469377768gmail_msg">One of the=
 two <font face=3D"courier new, monospace" class=3D"m_-1002852262469377768g=
mail_msg">Baz</font>-layers is redundant.</div><div class=3D"m_-10028522624=
69377768gmail_msg"><br class=3D"m_-1002852262469377768gmail_msg"></div><div=
 class=3D"m_-1002852262469377768gmail_msg">Logically, i want my implicit cl=
asses 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&#39;m missing someth=
ing? Thanks!</div></div>

<p class=3D"m_-1002852262469377768gmail_msg"></p>

-- <br class=3D"m_-1002852262469377768gmail_msg">
You received this message because you are subscribed to the Google Groups &=
quot;scala-language&quot; group.<br class=3D"m_-1002852262469377768gmail_ms=
g">
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>googlegroups.com</a>.<br class=3D"m_-1002852262469377768gmail_=
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>optout</a>.<br class=3D"m_-1002852262469377768gmail_msg">
</blockquote></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]" 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><br><br clear=3D"all"><div><br></div>-- <br>=
<div class=3D"gmail_signature" data-smartmail=3D"gmail_signature"><br>Marti=
n 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 />

--001a1148affa81d80c05430da06e--