Re: Is it a bug? Implicit map interferes with nonEmpty call

Kevin Wright <[email protected]> Sat, 22 Oct 2016 15:04:23 +0100
Newsgroups gmane.comp.lang.scala
Message-ID <CABHxxC0brpjwEe7=M40e2=k0X5m0ky3fFsyDK6WLO8zgQFXs-A@mail.gmail.com>
--001a1135da1ed033ce053f74a274
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

It=E2=80=99s not a bug=E2=80=A6 The problem is that you=E2=80=99re making a=
n implicit from a *very*
common type!

Strings don=E2=80=99t have a `nonEmpty` method, so when you try to invoke
=E2=80=9Cbaz=E2=80=9D.nonEmpty, the compiler will look for an implicit conv=
ersion to a type
that DOES have the method.

In this case, if finds the implicit Map.  This is because Map[A,B]
subclasses A =3D> B, and can therefore be used as an implicit conversion!

The conversion is attempted, but the function fails (because the map isn=E2=
=80=99t
defined for =E2=80=9Cbaz=E2=80=9D), and you get the error.

The solution?  Don=E2=80=99t make an implicit conversion from Strings like =
this,
especially against such a common type, it=E2=80=99s incredibly risky!



On 22 October 2016 at 13:53, Gallus Anonimus <[email protected]> wrote:

> Hi,
> In following code:
>
> object TheApp {
>
>   def main(args : Array[String]) {
>     implicit val innocentMap =3D Map("foo" -> Set("bar"))
>     "baz".nonEmpty
>   }
>
> }
> instead of computing expected true as "baz" string is non empty
> results in "java.util.NoSuchElementException: key not found: baz"
> I tested it on 2.10, 2.11.8, 2.12.RC2 with same results.
> The implicit innocentMap is the culprit.
> After decompiling "baz".nonEmpty looks like this:
> ((TraversableOnce)innocentMap.apply("baz")).nonEmpty();
>
> Can anyone tell me why innocentMap.apply is magically called here?
> Highly unexpected behaviour. If innocentMap has different type like:
> implicit val innocentMap =3D Map("foo" -> ("bar"))
> code behaves as expected.
>
> Sholud I report scala library bug?
>
> --
> 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
Kevin Wright
mail / hangouts / msn : [email protected]
quora: http://www.quora.com/Kevin-Wright
google+: http://gplus.to/thecoda
<[email protected]>
twitter: @thecoda
vibe / skype: kev.lee.wright

"My point today is that, if we wish to count lines of code, we should not
regard them as "lines produced" but as "lines spent": the current
conventional wisdom is so foolish as to book that count on the wrong side
of the ledger" ~ Dijkstra

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

--001a1135da1ed033ce053f74a274
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">It=E2=80=99s not a bug=E2=80=A6 The problem is that you=E2=
=80=99re making an implicit from a *very* common type!<div><br></div><div>S=
trings don=E2=80=99t have a `nonEmpty` method, so when you try to invoke =
=E2=80=9Cbaz=E2=80=9D.nonEmpty, the compiler will look for an implicit conv=
ersion to a type that DOES have the method.</div><div><br></div><div>In thi=
s case, if finds the implicit Map.=C2=A0 This is because Map[A,B] subclasse=
s A =3D&gt; B, and can therefore be used as an implicit conversion!</div><d=
iv><br></div><div>The conversion is attempted, but the function fails (beca=
use the map isn=E2=80=99t defined for =E2=80=9Cbaz=E2=80=9D), and you get t=
he error.</div><div><br></div><div>The solution?=C2=A0 Don=E2=80=99t make a=
n implicit conversion from Strings like this, especially against such a com=
mon type, it=E2=80=99s incredibly risky!</div><div><br></div><div><br></div=
></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On 22 Octo=
ber 2016 at 13:53, Gallus Anonimus <span dir=3D"ltr">&lt;<a href=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 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<br>In following code=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px" class=3D"m_-15628220181906=
10923prettyprint"><code class=3D"m_-1562822018190610923prettyprint"><div cl=
ass=3D"m_-1562822018190610923subprettyprint"><span style=3D"color:#008" cla=
ss=3D"m_-1562822018190610923styled-by-prettify">object</span><span style=3D=
"color:#000" class=3D"m_-1562822018190610923styled-by-prettify"> </span><sp=
an style=3D"color:#606" class=3D"m_-1562822018190610923styled-by-prettify">=
TheApp</span><span style=3D"color:#000" class=3D"m_-1562822018190610923styl=
ed-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-156282201819=
0610923styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_-1=
562822018190610923styled-by-prettify"><br>=C2=A0 <br>=C2=A0 </span><span st=
yle=3D"color:#008" class=3D"m_-1562822018190610923styled-by-prettify">def</=
span><span style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-pr=
ettify"> main</span><span style=3D"color:#660" class=3D"m_-1562822018190610=
923styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-15628=
22018190610923styled-by-prettify">args </span><span style=3D"color:#660" cl=
ass=3D"m_-1562822018190610923styled-by-prettify">:</span><span style=3D"col=
or:#000" class=3D"m_-1562822018190610923styled-by-prettify"> </span><span s=
tyle=3D"color:#606" class=3D"m_-1562822018190610923styled-by-prettify">Arra=
y</span><span style=3D"color:#660" class=3D"m_-1562822018190610923styled-by=
-prettify">[</span><span style=3D"color:#606" class=3D"m_-15628220181906109=
23styled-by-prettify">String</span><span style=3D"color:#660" class=3D"m_-1=
562822018190610923styled-by-prettify">])</span><span style=3D"color:#000" c=
lass=3D"m_-1562822018190610923styled-by-prettify"> </span><span style=3D"co=
lor:#660" class=3D"m_-1562822018190610923styled-by-prettify">{</span><span =
style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-prettify"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_-15628220181906=
10923styled-by-prettify">implicit</span><span style=3D"color:#000" class=3D=
"m_-1562822018190610923styled-by-prettify"> val innocentMap </span><span st=
yle=3D"color:#660" class=3D"m_-1562822018190610923styled-by-prettify">=3D</=
span><span style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-pr=
ettify"> </span><span style=3D"color:#606" class=3D"m_-1562822018190610923s=
tyled-by-prettify">Map</span><span style=3D"color:#660" class=3D"m_-1562822=
018190610923styled-by-prettify">(</span><span style=3D"color:#080" class=3D=
"m_-1562822018190610923styled-by-prettify">&quot;foo&quot;</span><span styl=
e=3D"color:#000" class=3D"m_-1562822018190610923styled-by-prettify"> </span=
><span style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-pretti=
fy">-&gt;</span><span style=3D"color:#000" class=3D"m_-1562822018190610923s=
tyled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_-156282201=
8190610923styled-by-prettify">Set</span><span style=3D"color:#660" class=3D=
"m_-1562822018190610923styled-by-prettify">(</span><span style=3D"color:#08=
0" class=3D"m_-1562822018190610923styled-by-prettify">&quot;bar&quot;</span=
><span style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-pretti=
fy">))</span><span style=3D"color:#000" class=3D"m_-1562822018190610923styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#080" class=
=3D"m_-1562822018190610923styled-by-prettify">&quot;baz&quot;</span><span s=
tyle=3D"color:#660" class=3D"m_-1562822018190610923styled-by-prettify">.</s=
pan><span style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-pre=
ttify">nonEmpty<br>=C2=A0 </span><span style=3D"color:#660" class=3D"m_-156=
2822018190610923styled-by-prettify">}</span><span style=3D"color:#000" clas=
s=3D"m_-1562822018190610923styled-by-prettify"><br>=C2=A0 <br></span><span =
style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-prettify">}</=
span><span style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-pr=
ettify"><br></span></div></code></div>instead of computing expected true as=
 &quot;baz&quot; string is non empty<br>results in &quot;java.util.<wbr>NoS=
uchElementException: key not found: baz&quot;<code class=3D"m_-156282201819=
0610923prettyprint"><span style=3D"color:#000" class=3D"m_-1562822018190610=
923styled-by-prettify"><br></span></code>I tested it on 2.10, 2.11.8, 2.12.=
RC2 with same results.<br>The implicit innocentMap is the culprit.<br>After=
 decompiling &quot;baz&quot;.nonEmpty looks like this:<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px" class=3D"m_-1562822018190610923prettyprint"><code cl=
ass=3D"m_-1562822018190610923prettyprint"><div class=3D"m_-1562822018190610=
923subprettyprint"><span style=3D"color:#660" class=3D"m_-15628220181906109=
23styled-by-prettify">((</span><span style=3D"color:#606" class=3D"m_-15628=
22018190610923styled-by-prettify">TraversableOnce</span><span style=3D"colo=
r:#660" class=3D"m_-1562822018190610923styled-by-prettify">)</span><span st=
yle=3D"color:#000" class=3D"m_-1562822018190610923styled-by-prettify">innoc=
entMap</span><span style=3D"color:#660" class=3D"m_-1562822018190610923styl=
ed-by-prettify">.</span><span style=3D"color:#000" class=3D"m_-156282201819=
0610923styled-by-prettify"><wbr>apply</span><span style=3D"color:#660" clas=
s=3D"m_-1562822018190610923styled-by-prettify">(</span><span style=3D"color=
:#080" class=3D"m_-1562822018190610923styled-by-prettify">&quot;baz&quot;</=
span><span style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-pr=
ettify">)).</span><span style=3D"color:#000" class=3D"m_-156282201819061092=
3styled-by-prettify">nonEmpty</span><span style=3D"color:#660" class=3D"m_-=
1562822018190610923styled-by-prettify">();</span></div></code></div><br>Can=
 anyone tell me why innocentMap.apply is magically called here?<br>Highly u=
nexpected behaviour. If innocentMap has different type like:<br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px" class=3D"m_-1562822018190610923prettyprint"><=
code class=3D"m_-1562822018190610923prettyprint"><div class=3D"m_-156282201=
8190610923subprettyprint"><span style=3D"color:#008" class=3D"m_-1562822018=
190610923styled-by-prettify">implicit</span><span style=3D"color:#000" clas=
s=3D"m_-1562822018190610923styled-by-prettify"> val innocentMap </span><spa=
n style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-prettify">=
=3D</span><span style=3D"color:#000" class=3D"m_-1562822018190610923styled-=
by-prettify"> </span><span style=3D"color:#606" class=3D"m_-156282201819061=
0923styled-by-prettify">Map</span><span style=3D"color:#660" class=3D"m_-15=
62822018190610923styled-by-prettify">(</span><span style=3D"color:#080" cla=
ss=3D"m_-1562822018190610923styled-by-prettify">&quot;foo&quot;</span><span=
 style=3D"color:#000" class=3D"m_-1562822018190610923styled-by-prettify"> <=
/span><span style=3D"color:#660" class=3D"m_-1562822018190610923styled-by-p=
rettify">-&gt;</span><span style=3D"color:#000" class=3D"m_-156282201819061=
0923styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-1562=
822018190610923styled-by-prettify">(</span><span style=3D"color:#080" class=
=3D"m_-1562822018190610923styled-by-prettify">&quot;bar&quot;</span><span s=
tyle=3D"color:#660" class=3D"m_-1562822018190610923styled-by-prettify">))</=
span></div></code></div>code behaves as expected.<br><br>Sholud I report sc=
ala library bug?<span class=3D"HOEnZb"><font color=3D"#888888"><br></font><=
/span></div><span class=3D"HOEnZb"><font color=3D"#888888">

<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>
</font></span></blockquote></div><br><br clear=3D"all"><div><br></div>-- <b=
r><div class=3D"gmail_signature" data-smartmail=3D"gmail_signature"><div di=
r=3D"ltr"><div>Kevin Wright<br>mail / hangouts / msn : <a href=3D"mailto:ke=
[email protected]" target=3D"_blank">[email protected]</a><div>=
<div><div>quora:=C2=A0<a href=3D"http://www.quora.com/Kevin-Wright" target=
=3D"_blank">http://www.quora.com/Kevin-Wright</a></div>google+:=C2=A0<a hre=
f=3D"http://gplus.to/thecoda" target=3D"_blank">http://gplus.to/thecoda</a>=
<br><div><a href=3D"mailto:[email protected]" target=3D"_blank"></a>=
</div><div>twitter: @thecoda<br></div></div><div>vibe / skype: kev.lee.wrig=
ht</div><div><br></div><div><font face=3D"tahoma, sans-serif" color=3D"#666=
666"><span style=3D"line-height:22px"><span style=3D"line-height:normal">&q=
uot;My point today is that, if we wish to count lines of code, we should no=
t regard them as &quot;lines produced&quot; but as &quot;lines spent&quot;:=
 the current conventional wisdom is so foolish as to book that count on the=
 wrong side of the ledger&quot; ~ Dijkstra</span></span></font></div></div>=
</div></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 />

--001a1135da1ed033ce053f74a274--