This page is no longer maintained — Please continue to the home page at www.scala-lang.org

2.8 BigDecimal implicits

17 replies
Carsten Saager
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
I had a weird regression today (I am moving some projects to 2.8):

import BigDecimal._
val a ="abc"
val b ="abd"
Console.print(a>b)
bd.scala:6: error: type mismatch;
 found   : java.lang.String
 required: ?{val >: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method string2bigDecimal in object BigDecimal of type (s: String)BigDecimal
 and method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
 are possible conversion functions from java.lang.String to ?{val >: ?}
Console.print(a>b)
              ^
one error found

BigDecimal has since 2.8 an implicit to convert from String to BigDecimal that makes lexical comparison of String unusable

-Carsten
Carsten Saager
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
2.8 BigDecimal implicits
I had a weird regression today (I am moving some projects to 2.8):

import BigDecimal._
val a ="abc"
val b ="abd"
Console.print(a>b)
bd.scala:6: error: type mismatch;
 found   : java.lang.String
 required: ?{val >: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method string2bigDecimal in object BigDecimal of type (s: String)BigDecimal
 and method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
 are possible conversion functions from java.lang.String to ?{val >: ?}
Console.print(a>b)
              ^
one error found

BigDecimal has since 2.8 an implicit to convert from String to BigDecimal that makes lexical comparison of String unusable

-Carsten
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8 BigDecimal implicits

On Mon, Oct 05, 2009 at 04:23:37PM +0200, Carsten Saager wrote:
> BigDecimal has since 2.8 an implicit to convert from String to
> BigDecimal that makes lexical comparison of String unusable

It looks like those implicits were added in response to this ticket.

http://lampsvn.epfl.ch/trac/scala/ticket/1813

I am very very skeptical of that sort of blanket addition of implicits,
and I think we need a clearer policy. Come to think of it I would say
every addition of an implicit to the standard library ought to be
reviewed by somebody else (and I am definitely not a guy who likes
adding processes.)

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: 2.8 BigDecimal implicits

On Mon, Oct 5, 2009 at 6:25 PM, Paul Phillips wrote:
> On Mon, Oct 05, 2009 at 04:23:37PM +0200, Carsten Saager wrote:
>> BigDecimal has since 2.8 an implicit to convert from String to
>> BigDecimal that makes lexical comparison of String unusable
>
> It looks like those implicits were added in response to this ticket.
>
>  http://lampsvn.epfl.ch/trac/scala/ticket/1813
>
> I am very very skeptical of that sort of blanket addition of implicits,
> and I think we need a clearer policy.  Come to think of it I would say
> every addition of an implicit to the standard library ought to be
> reviewed by somebody else (and I am definitely not a guy who likes
> adding processes.)
>
+1

And we need to back out of the fix for ticket 1813. 1813 should be a won't fix.

Martin

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: 2.8 BigDecimal implicits
+1 for such a policy.

I also think the implicits in JavaConversions should be reviewed.

At the very least, if implicits are to be added, they should be in the
smallest possible scope so that they are not imported by mistake or
jointly with something else that needs to be imported (as was the case
with BigDecimal).

--j

On Mon, Oct 5, 2009 at 9:25 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Mon, Oct 05, 2009 at 04:23:37PM +0200, Carsten Saager wrote:
> BigDecimal has since 2.8 an implicit to convert from String to
> BigDecimal that makes lexical comparison of String unusable

It looks like those implicits were added in response to this ticket.

 http://lampsvn.epfl.ch/trac/scala/ticket/1813

I am very very skeptical of that sort of blanket addition of implicits,
and I think we need a clearer policy.  Come to think of it I would say
every addition of an implicit to the standard library ought to be
reviewed by somebody else (and I am definitely not a guy who likes
adding processes.)

--
Paul Phillips      | It's better to have gloved and tossed than never to
Moral Alien        | have played baseball.
Empiricist         |
i pull his palp!   |----------* http://www.improving.org/paulp/ *----------

ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: 2.8 BigDecimal implicits

On Mon, 2009-10-05 at 10:58 -0700, Jorge Ortiz wrote:
> I also think the implicits in JavaConversions should be reviewed.

Maybe you could do it since you have the experience while working on
scala-javautils?

Best,
Ismael

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: 2.8 BigDecimal implicits
It may be worth clarifying, if only to save someone else the hour or so I once spent blankly wondering from whence a particular implicit conversion appeared, that one doesn't need to import BigDecimal._ to bring this into play. The implicit scope (§7.2, §7.3 of the Scala Reference) of the type BigDecimal is does this for you if a value of type BigDecimal is called for:

scala> val a = BigDecimal("1")
a: BigDecimal = 1

scala> a + "2"
res0: BigDecimal = 3

-jason

On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:

At the very least, if implicits are to be added, they should be in the
smallest possible scope so that they are not imported by mistake or
jointly with something else that needs to be imported (as was the case
with BigDecimal).

--j
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: 2.8 BigDecimal implicits
And, somewhat amusingly, the (only?) way to hide implicits from the implicit scope is to add intentionally ambiguous implicits to the local scope:

scala> val a = BigDecimal("2")
a: BigDecimal = 2

scala> a * "3"
res0: BigDecimal = 6

scala> implicit val ambig1, ambig2 = BigDecimal.string2bigDecimal _
ambig1: (String) => BigDecimal = <function1>
ambig2: (String) => BigDecimal = <function1>

scala> a * "3"                                                    
<console>:8: error: type mismatch;
 found   : java.lang.String("3")
 required: BigDecimal
Note that implicit conversions are not applicable because they are ambiguous:
 both value ambig1 in object $iw of type => (String) => BigDecimal
 and value ambig2 in object $iw of type => (String) => BigDecimal
 are possible conversion functions from java.lang.String("3") to BigDecimal
       a * "3"
           ^

On Mon, Oct 5, 2009 at 11:37 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
It may be worth clarifying, if only to save someone else the hour or so I once spent blankly wondering from whence a particular implicit conversion appeared, that one doesn't need to import BigDecimal._ to bring this into play. The implicit scope (§7.2, §7.3 of the Scala Reference) of the type BigDecimal is does this for you if a value of type BigDecimal is called for:

scala> val a = BigDecimal("1")
a: BigDecimal = 1

scala> a + "2"
res0: BigDecimal = 3
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8 BigDecimal implicits

On Mon, Oct 05, 2009 at 11:58:15PM +0200, Jason Zaugg wrote:
> And, somewhat amusingly, the (only?) way to hide implicits from the
> implicit scope is to add intentionally ambiguous implicits to the
> local scope:

The intentional ambiguity strategy reaches maximum comedy in the story
of RichUnit:

http://www.scala-lang.org/node/2301

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: 2.8 BigDecimal implicits

On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz wrote:
> +1 for such a policy.
>
> I also think the implicits in JavaConversions should be reviewed.
>
Hi Jorge,

Do you have specific complaints about this one? The conversions were
added sort of as a replacement for jcl. The alternative would have
been to make Scala collections subtypes of matching Java collections
(and possibly have implicit conversions the other way).
But there was resistance against this, for instance because it was
felt that Scala iterators should not automatically inherit Java's
remove method.

I am actually quite ambivalent about the whole matter.

Cheers

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: 2.8 BigDecimal implicits

On Wed, Oct 7, 2009 at 1:28 PM, martin odersky wrote:
> On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz wrote:
>> +1 for such a policy.
>>
>> I also think the implicits in JavaConversions should be reviewed.
>>
> Hi Jorge,
>
> Do you have specific complaints about this one? The conversions were
> added sort of as a replacement for jcl. The alternative would have
> been to make Scala collections subtypes of matching Java collections
> (and possibly have implicit conversions the other way).
> But there was resistance against this, for instance because it was
> felt that Scala iterators should not automatically inherit Java's
> remove method.
>
> I am actually quite ambivalent about the whole matter.

I think Jorge's main complaint is about the implicitness of the new
JavaConversions rather than anything else.

I don't believe implicitness does any harm here ... specific examples
of potential issues relating to these particular conversions (rather
than blanket admonitions against implicits in general) would be very
helpful.

I'm prettys sure that if we don't provide the implicits in some form,
they'll be implemented over and over again ... and that would be
undesirable.

As ever, it'd be nice to have a general solution to the problem of
enabling/disabling implicitness on a use site basis.

Cheers,

Miles

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 BigDecimal implicits

On Wednesday 07 October 2009 15:49:52 Miles Sabin wrote:
> As ever, it'd be nice to have a general solution to the problem of
> enabling/disabling implicitness on a use site basis.

Really? How often do you have the need to implicitly create a BigDecimal out
of a String? Wouldn't it be better to let the developers that need that
feature write the one line of code required to create a conversion themselves?

On Wednesday 07 October 2009 15:49:52 Miles Sabin wrote:
> On Wed, Oct 7, 2009 at 1:28 PM, martin odersky
wrote:
> > On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz wrote:
> >> +1 for such a policy.
> >>
> >> I also think the implicits in JavaConversions should be reviewed.
> >
> > Hi Jorge,
> >
> > Do you have specific complaints about this one? The conversions were
> > added sort of as a replacement for jcl. The alternative would have
> > been to make Scala collections subtypes of matching Java collections
> > (and possibly have implicit conversions the other way).
> > But there was resistance against this, for instance because it was
> > felt that Scala iterators should not automatically inherit Java's
> > remove method.
> >
> > I am actually quite ambivalent about the whole matter.
>
> I think Jorge's main complaint is about the implicitness of the new
> JavaConversions rather than anything else.
>
> I don't believe implicitness does any harm here ... specific examples
> of potential issues relating to these particular conversions (rather
> than blanket admonitions against implicits in general) would be very
> helpful.
>
> I'm prettys sure that if we don't provide the implicits in some form,
> they'll be implemented over and over again ... and that would be
> undesirable.
>
> As ever, it'd be nice to have a general solution to the problem of
> enabling/disabling implicitness on a use site basis.
>
> Cheers,
>
>
> Miles
>

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: 2.8 BigDecimal implicits

On Wed, Oct 7, 2009 at 3:22 PM, David Flemström
wrote:
> On Wednesday 07 October 2009 15:49:52 Miles Sabin wrote:
>> As ever, it'd be nice to have a general solution to the problem of
>> enabling/disabling implicitness on a use site basis.
>
> Really? How often do you have the need to implicitly create a BigDecimal out
> of a String?

Never.

> Wouldn't it be better to let the developers that need that feature write the
> one line of code required to create a conversion themselves?

Certainly.

That's not the conversion I was talking about.

Cheers,

Miles

Iulian Dragos
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 BigDecimal implicits


On Mon, Oct 5, 2009 at 11:58 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
And, somewhat amusingly, the (only?) way to hide implicits from the implicit scope is to add intentionally ambiguous implicits to the local scope:

No, the other way is to 'unimport' the definition in Predef. Since Predef is imported implicitly at the beginning of every compilation unit, one can import it explicitly and hide the undesired conversion:

import Predef.{augmentString => _}

object Main extends Application {
  "abc".map(_.toUpper)
}

$ bscalac -d classes impl.scala
impl.scala:5: error: value map is not a member of java.lang.String
  "abc".map(_.toUpper)
        ^
one error found

This won't work in the interpreter, since it inserts each line of text in a wrapper object definition, therefore Predef is imported implicitly at the beginning of the file, and the second import won't change anything.

Otherwise, I'm totally in favor of keeping implicits in Predef to a minimum, as most DSLs will want to operate on primitive values, quickly leading to ambiguity errors.

iulian

 

scala> val a = BigDecimal("2")
a: BigDecimal = 2

scala> a * "3"
res0: BigDecimal = 6

scala> implicit val ambig1, ambig2 = BigDecimal.string2bigDecimal _
ambig1: (String) => BigDecimal = <function1>
ambig2: (String) => BigDecimal = <function1>

scala> a * "3"                                                    
<console>:8: error: type mismatch;
 found   : java.lang.String("3")
 required: BigDecimal
Note that implicit conversions are not applicable because they are ambiguous:
 both value ambig1 in object $iw of type => (String) => BigDecimal
 and value ambig2 in object $iw of type => (String) => BigDecimal
 are possible conversion functions from java.lang.String("3") to BigDecimal
       a * "3"
           ^

On Mon, Oct 5, 2009 at 11:37 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
It may be worth clarifying, if only to save someone else the hour or so I once spent blankly wondering from whence a particular implicit conversion appeared, that one doesn't need to import BigDecimal._ to bring this into play. The implicit scope (§7.2, §7.3 of the Scala Reference) of the type BigDecimal is does this for you if a value of type BigDecimal is called for:

scala> val a = BigDecimal("1")
a: BigDecimal = 1

scala> a + "2"
res0: BigDecimal = 3



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: 2.8 BigDecimal implicits
Martin, Miles,

I don't have any complaints about JavaConversions, but I also haven't had much time to look into them or try to abuse their implicitness. On cursory inspection they are indeed much better safer than their jcl counterparts, but I've been surprised in the past at the damage that seemingly "safe" implicits can cause. For just one recent example, consider the clash between Java 1.5/1.6 and RichString's isEmpty method. This was surprising to me and as far as I know not foreseen by anyone else. I'd just like to be sure that as many possibly dangerous corner cases as possible have been thought of and successfully avoided. Hence the word "review".

--j

On Wed, Oct 7, 2009 at 6:49 AM, Miles Sabin <miles [at] milessabin [dot] com> wrote:
On Wed, Oct 7, 2009 at 1:28 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
> On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
>> +1 for such a policy.
>>
>> I also think the implicits in JavaConversions should be reviewed.
>>
> Hi Jorge,
>
> Do you have specific complaints about this one? The conversions were
> added sort of as a replacement for jcl. The alternative would have
> been to make Scala collections subtypes of matching Java collections
> (and possibly have implicit conversions the other way).
> But there was resistance against this, for instance because it was
> felt that Scala iterators should not automatically inherit Java's
> remove method.
>
> I am actually quite ambivalent about the whole matter.

I think Jorge's main complaint is about the implicitness of the new
JavaConversions rather than anything else.

I don't believe implicitness does any harm here ... specific examples
of potential issues relating to these particular conversions (rather
than blanket admonitions against implicits in general) would be very
helpful.

I'm prettys sure that if we don't provide the implicits in some form,
they'll be implemented over and over again ... and that would be
undesirable.

As ever, it'd be nice to have a general solution to the problem of
enabling/disabling implicitness on a use site basis.

Cheers,


Miles

--
Miles Sabin
tel: +44 (0)7813 944 528
skype:  milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: 2.8 BigDecimal implicits
That works fine for implicits defined in Predef, but not for implicits defined on the companion objects of traits/classes, which fall in the 'implicit scope'.

For example, the following compiles, in line with the spec.

object Test {
  import BigDecimal.{int2bigDecimal => _ }
  BigDecimal("2") * 3
}

My point is that implicits on companion objects should be with as much, if not more, caution that those in Predef.

-jason

On Wed, Oct 7, 2009 at 5:18 PM, Iulian Dragos <jaguarul [at] gmail [dot] com> wrote:


On Mon, Oct 5, 2009 at 11:58 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
And, somewhat amusingly, the (only?) way to hide implicits from the implicit scope is to add intentionally ambiguous implicits to the local scope:

No, the other way is to 'unimport' the definition in Predef. Since Predef is imported implicitly at the beginning of every compilation unit, one can import it explicitly and hide the undesired conversion:

import Predef.{augmentString => _}

object Main extends Application {
  "abc".map(_.toUpper)
}

$ bscalac -d classes impl.scala
impl.scala:5: error: value map is not a member of java.lang.String
  "abc".map(_.toUpper)
        ^
one error found

This won't work in the interpreter, since it inserts each line of text in a wrapper object definition, therefore Predef is imported implicitly at the beginning of the file, and the second import won't change anything.

Otherwise, I'm totally in favor of keeping implicits in Predef to a minimum, as most DSLs will want to operate on primitive values, quickly leading to ambiguity errors.

iulian

 

scala> val a = BigDecimal("2")
a: BigDecimal = 2

scala> a * "3"
res0: BigDecimal = 6

scala> implicit val ambig1, ambig2 = BigDecimal.string2bigDecimal _
ambig1: (String) => BigDecimal = <function1>
ambig2: (String) => BigDecimal = <function1>

scala> a * "3"                                                    
<console>:8: error: type mismatch;
 found   : java.lang.String("3")
 required: BigDecimal
Note that implicit conversions are not applicable because they are ambiguous:
 both value ambig1 in object $iw of type => (String) => BigDecimal
 and value ambig2 in object $iw of type => (String) => BigDecimal
 are possible conversion functions from java.lang.String("3") to BigDecimal
       a * "3"
           ^

On Mon, Oct 5, 2009 at 11:37 PM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
It may be worth clarifying, if only to save someone else the hour or so I once spent blankly wondering from whence a particular implicit conversion appeared, that one doesn't need to import BigDecimal._ to bring this into play. The implicit scope (§7.2, §7.3 of the Scala Reference) of the type BigDecimal is does this for you if a value of type BigDecimal is called for:

scala> val a = BigDecimal("1")
a: BigDecimal = 1

scala> a + "2"
res0: BigDecimal = 3



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 BigDecimal implicits

On Wed, Oct 7, 2009 at 7:49 AM, Miles Sabin wrote:
> On Wed, Oct 7, 2009 at 1:28 PM, martin odersky wrote:
>> On Mon, Oct 5, 2009 at 7:58 PM, Jorge Ortiz wrote:
>>> +1 for such a policy.
>>>
>>> I also think the implicits in JavaConversions should be reviewed.
>>>
>> Hi Jorge,
>>
>> Do you have specific complaints about this one? The conversions were
>> added sort of as a replacement for jcl. The alternative would have
>> been to make Scala collections subtypes of matching Java collections
>> (and possibly have implicit conversions the other way).
>> But there was resistance against this, for instance because it was
>> felt that Scala iterators should not automatically inherit Java's
>> remove method.
>>
>> I am actually quite ambivalent about the whole matter.

Having used Jorge's collections interop code a fair bit, I have to say
that I really like the approach of having the implicits responsible
solely for providing "asJava" and "asScala" methods rather than
implicit conversion between the collection types themselves. In a
mixed codebase, having the implicit conversions go directly between
the collection types can obscure cases where one may be performing
excessive conversions; if you instead simply have the implicits
provide "asJava" and "asScala" then the conversion is facilitated but
is explicit.

Kris

>
> I think Jorge's main complaint is about the implicitness of the new
> JavaConversions rather than anything else.
>
> I don't believe implicitness does any harm here ... specific examples
> of potential issues relating to these particular conversions (rather
> than blanket admonitions against implicits in general) would be very
> helpful.
>
> I'm prettys sure that if we don't provide the implicits in some form,
> they'll be implemented over and over again ... and that would be
> undesirable.
>
> As ever, it'd be nice to have a general solution to the problem of
> enabling/disabling implicitness on a use site basis.
>
> Cheers,
>
>
> Miles
>
> --
> Miles Sabin
> tel: +44 (0)7813 944 528
> skype:  milessabin
> http://www.chuusai.com/
> http://twitter.com/milessabin
>

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: 2.8 BigDecimal implicits

On Thu, Oct 8, 2009 at 1:48 AM, Kris Nuttycombe
wrote:
> In a mixed codebase, having the implicit conversions go directly between
> the collection types can obscure cases where one may be performing
> excessive conversions

The conversions in scala.collection.JavaConversion are extremely
cheap, and designed to accomodate repeated conversion of the same
collection object smoothly and cheaply (essentially it's a
boxing/unboxing operation).

Could you say a little more about what you mean by "excessive" conversions?

Cheers,

Miles

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland