Bei der Gruppe, für die Sie eine Mitteilung verfassen, handelt es sich um eine Usenet-Gruppe. Wenn Sie in dieser Gruppe Nachrichten posten, ist Ihre E-Mail-Adresse für jeden im Internet sichtbar
I have pull requests for most outstanding value class tickets. We can now
handle the infamous bridge methods of SI-6260, even though error messages
can be improved. The crash when interacting with lazy vals is gone. Other
problems are solved by restrictions:
- no value classes in structural refinements
- value classes cannot unbox to other derived value classes.
It strikes me that in all this the previous suspect, fully polymorphic
value classes, did not make a difference, contrary to what I had assumed
and feared. So, should we still introduce that restriction, or drop it and
allow fully polymorphic value classes? I would be now be in favor of
dropping the restriction, but could probably be convinced otherwise.
Cheers
- Martin
On Sat, Sep 15, 2012 at 9:57 PM, Pavel Pavlov <pavel.e.pav...@gmail.com>wrote:
On Mon, Sep 17, 2012 at 9:25 AM, martin odersky <martin.oder...@epfl.ch> wrote:
> It strikes me that in all this the previous suspect, fully polymorphic value
> classes, did not make a difference, contrary to what I had assumed and
> feared. So, should we still introduce that restriction, or drop it and allow
> fully polymorphic value classes? I would be now be in favor of dropping the
> restriction, but could probably be convinced otherwise.
Test cases would be instrumental in convincing us one way or the
other. If anyone out there has some time to exercise value classes
(the referenced bugs will be helpful in guiding what sorts of things
to test) it would be very helpful.
Sie müssen sich anmelden, bevor Sie Nachrichten veröffentlichen können.
martin odersky <martin.oder...@epfl.ch> wrote:
> So here is the current status:
> I have pull requests for most outstanding value class tickets. We can now
> handle the infamous bridge methods of SI-6260, even though error messages
> can be improved. The crash when interacting with lazy vals is gone.
There is a problem with type parameters getting messed up. See my last comment in:
> It strikes me that in all this the previous suspect, fully polymorphic
> value classes, did not make a difference, contrary to what I had assumed
> and feared. So, should we still introduce that restriction, or drop it and
> allow fully polymorphic value classes? I would be now be in favor of
> dropping the restriction, but could probably be convinced otherwise.
I don't know what the underlying cause is, but see:
object test2a { def main(args: Array[String]) { val b1 = new Box1(null) val b2 = new Box2(null) val f: Foo[Box2] = b1 println(f.foo("")) println(f.foo(b2)) }
}
============== produce compile error: ----- test2a.scala:8: error: double definition: method foo:(x: Box2)String and method foo:(x: String)String at line 7 have same type after erasure: (x: String)String def foo(x: Box2) = "foo(Box2): ok" ^ one error found -----
while almost identical == test2b.scala == trait Foo[T <: AnyVal] extends Any { def foo(x: String): String def foo(x: T): String
object test2b { def main(args: Array[String]) { val b2 = new Box2(null) val f: Foo[Box2] = b2 println(f.foo("")) println(f.foo(b2)) }
}
============== compiles and runs flawlessly: ----- foo(String): ok foo(Box2): ok -----
All these are variations of the same bug with non-uniform value-class-unboxing in method signatures (I've tried to draw attention to this problem twice in this thread but with no luck).
On Monday, September 17, 2012 11:26:06 PM UTC+7, Martin wrote:
> So here is the current status:
> I have pull requests for most outstanding value class tickets. We can now > handle the infamous bridge methods of SI-6260, even though error messages > can be improved. The crash when interacting with lazy vals is gone. Other > problems are solved by restrictions:
> - no value classes in structural refinements > - value classes cannot unbox to other derived value classes.
> It strikes me that in all this the previous suspect, fully polymorphic > value classes, did not make a difference, contrary to what I had assumed > and feared. So, should we still introduce that restriction, or drop it and > allow fully polymorphic value classes? I would be now be in favor of > dropping the restriction, but could probably be convinced otherwise.
> Cheers
> - Martin
> On Sat, Sep 15, 2012 at 9:57 PM, Pavel Pavlov <pavel.e...@gmail.com<javascript:> > > wrote:
>> On Sunday, September 16, 2012 2:52:07 AM UTC+7, Paul Phillips wrote:
>>> On Sat, Sep 15, 2012 at 12:30 PM, Pavel Pavlov <pavel.e...@gmail.com>wrote:
>>>> ) val f has type `$anon`.
>>> Right, this is the case I am talking about - it should be the >>> overwhelming majority of cases.
>> And this is _exactly_ the case for totally safe & cheap[1] >> inlining/closure elimination.
>> [1] Cheap in terms of required static analysis: this case require no >> analysis at all, so all transformations can be done right in ASTs.
Actually, can you open a new bug for this? Also thanks much for the reports. We've been listening, even if you haven't seen it on the ML. Value classes are top of my discussion for the Scala meeting today.
> object test2b { > def main(args: Array[String]) { > val b2 = new Box2(null) > val f: Foo[Box2] = b2 > println(f.foo("")) > println(f.foo(b2)) > } > } > ============== > compiles and runs flawlessly: > ----- > foo(String): ok > foo(Box2): ok > -----
> All these are variations of the same bug with non-uniform > value-class-unboxing in method signatures (I've tried to draw attention to > this problem twice in this thread but with no luck).
> These bugs looks very similar to SI-6385 for me.
> On Monday, September 17, 2012 11:26:06 PM UTC+7, Martin wrote:
>> So here is the current status:
>> I have pull requests for most outstanding value class tickets. We can now >> handle the infamous bridge methods of SI-6260, even though error messages >> can be improved. The crash when interacting with lazy vals is gone. Other >> problems are solved by restrictions:
>> - no value classes in structural refinements >> - value classes cannot unbox to other derived value classes.
>> It strikes me that in all this the previous suspect, fully polymorphic >> value classes, did not make a difference, contrary to what I had assumed >> and feared. So, should we still introduce that restriction, or drop it and >> allow fully polymorphic value classes? I would be now be in favor of >> dropping the restriction, but could probably be convinced otherwise.
>> Cheers
>> - Martin
>> On Sat, Sep 15, 2012 at 9:57 PM, Pavel Pavlov <pavel.e...@gmail.com>wrote:
>>> On Sunday, September 16, 2012 2:52:07 AM UTC+7, Paul Phillips wrote:
>>>> On Sat, Sep 15, 2012 at 12:30 PM, Pavel Pavlov <pavel.e...@gmail.com>wrote:
>>>>> ) val f has type `$anon`.
>>>> Right, this is the case I am talking about - it should be the >>>> overwhelming majority of cases.
>>> And this is _exactly_ the case for totally safe & cheap[1] >>> inlining/closure elimination.
>>> [1] Cheap in terms of required static analysis: this case require no >>> analysis at all, so all transformations can be done right in ASTs.
I'd be fine with disallowing overloading involving value classes entirely.
I think we can disallow a great deal where value classes are involved and
still hang onto the great majority of the current uses, which I am loathe
to give up. I have watched erasure bugs like these go unsolved for years
so it stretches credulity to think we will be dashing off non-regrettable
solutions for 2.10.
Sie müssen sich anmelden, bevor Sie Nachrichten veröffentlichen können.
On Mon, Sep 17, 2012 at 10:58 PM, Mark Harrah <dmhar...@gmail.com> wrote:
> On Mon, 17 Sep 2012 18:25:45 +0200
> martin odersky <martin.oder...@epfl.ch> wrote:
> > So here is the current status:
> > I have pull requests for most outstanding value class tickets. We can now
> > handle the infamous bridge methods of SI-6260, even though error messages
> > can be improved. The crash when interacting with lazy vals is gone.
> There is a problem with type parameters getting messed up. See my last
> comment in:
> I have to dig a bit deeper on that one.
> > It strikes me that in all this the previous suspect, fully polymorphic
> > value classes, did not make a difference, contrary to what I had assumed
> > and feared. So, should we still introduce that restriction, or drop it
> and
> > allow fully polymorphic value classes? I would be now be in favor of
> > dropping the restriction, but could probably be convinced otherwise.
> I don't know what the underlying cause is, but see:
On Tue, Sep 18, 2012 at 4:33 PM, Paul Phillips <pa...@improving.org> wrote:
> I'd be fine with disallowing overloading involving value classes entirely.
> I think we can disallow a great deal where value classes are involved and
> still hang onto the great majority of the current uses, which I am loathe
> to give up. I have watched erasure bugs like these go unsolved for years
> so it stretches credulity to think we will be dashing off non-regrettable
> solutions for 2.10.
I now also think that the "partial unboxing" which was done to allow
overloading in value classes is more trouble than it's worth.
To remind everyone:
Partial unboxing was put in so we could write code like:
With complete unboxing both erased signatures of "/" would be
(Double)Double, so we'd get a clash. With partial unboxing, "Meter" in the
value class itself would not be erased.
However, this irregularity leads to surprising bridge methods which are not
working correctly. That was Pavel's example (which I append below).
Now, I would argue that the scheme is too limiting anyway, and that there
exist more robust ways to avoid name clashes.
Too limited:
1) If we abstract out the operations into a universal trait, we do get an
erasure clash:
trait MeterTrait extends Any {
def / (other: Meter): Double
def / (other: Double): Meter
}
class Meter(x: Double) extends AnyVal with MeterTrait {
def / (other: Meter): Double = ...
def / (other: Double): Meter = ...
}
2) If we mix more than one value class we also get erasure clashes, as in:
class Meter(x: Double) extends AnyVal {
def / (other: Second): Speed = ...
def / (other: Double): Meter = ...
}
class Second(x: Double) extends AnyVal ...
So the trick does not buy us much. Furthermore, we know that we can
disambiguate more robustly using implicit phantom parameters. E.g.
class Meter(x: Double) extends AnyVal {
def / (other: Meter)(implicit dummy: MeterArg = null) = ...
def / (other: Double): Meter = ...
}
object Meter {
trait MeterArg
}
While I am not in a position to make well thought-through proposals on this matter, I would like to say that
less magic + more regular = profit!
With that I mean more direct error messages (possibly with a clear work-around suggestion) instead of searching for why things break at a completely different place in the code mysteriously. If that means writing a few more characters as a library implementor, that’s a price I consider to be small.
> On Tue, Sep 18, 2012 at 4:33 PM, Paul Phillips <pa...@improving.org> wrote:
> I'd be fine with disallowing overloading involving value classes entirely. I think we can disallow a great deal where value classes are involved and still hang onto the great majority of the current uses, which I am loathe to give up. I have watched erasure bugs like these go unsolved for years so it stretches credulity to think we will be dashing off non-regrettable solutions for 2.10.
> I now also think that the "partial unboxing" which was done to allow overloading in value classes is more trouble than it's worth.
> To remind everyone:
> Partial unboxing was put in so we could write code like:
> With complete unboxing both erased signatures of "/" would be (Double)Double, so we'd get a clash. With partial unboxing, "Meter" in the value class itself would not be erased.
> However, this irregularity leads to surprising bridge methods which are not working correctly. That was Pavel's example (which I append below).
> Now, I would argue that the scheme is too limiting anyway, and that there exist more robust ways to avoid name clashes.
> Too limited:
> 1) If we abstract out the operations into a universal trait, we do get an erasure clash:
> trait MeterTrait extends Any {
> def / (other: Meter): Double
> def / (other: Double): Meter
> }
> class Meter(x: Double) extends AnyVal with MeterTrait {
> def / (other: Meter): Double = ...
> def / (other: Double): Meter = ...
> }
> 2) If we mix more than one value class we also get erasure clashes, as in:
On Wed, Sep 19, 2012 at 11:20:08AM +0200, martin odersky wrote:
> I now also think that the "partial unboxing" which was done to allow
> overloading in value classes is more trouble than it's worth.
...
> With complete unboxing both erased signatures of "/" would be
> (Double)Double, so we'd get a clash. With partial unboxing, "Meter" in the
> value class itself would not be erased.
> However, this irregularity leads to surprising bridge methods which are not
> working correctly. That was Pavel's example (which I append below).
> Now, I would argue that the scheme is too limiting anyway, and that there
> exist more robust ways to avoid name clashes.
...
> So, I am for removing this special case.
> What do people think?
+1
Given that value classes currently exist primarily to avoid boxing I
support removing this feature, especially since it seems to add a lot
of complexity to the implementation. Users of value classes shouldn't
expect them to work like normal types in these cases.
-- Erik
Sie müssen sich anmelden, bevor Sie Nachrichten veröffentlichen können.
that eliminates halfboxing. Several reported bugs disappeared: Mark's last
variant of 3667, 3685 as well as Pavel's counter-examples on this list. So
this looks like a definite win.
With that pull-request we are currently good again: I see no more
outstanding critical bugs against value classes, except that we have to fix
the Java generic signatures. That should also be simpler now because
erasure got more regular.
More tests are very much appreciated.
Cheers
- Martin
On Wed, Sep 19, 2012 at 4:57 PM, Erik Osheim <e...@plastic-idolatry.com>wrote:
> On Wed, Sep 19, 2012 at 11:20:08AM +0200, martin odersky wrote:
> > I now also think that the "partial unboxing" which was done to allow
> > overloading in value classes is more trouble than it's worth.
> ...
> > With complete unboxing both erased signatures of "/" would be
> > (Double)Double, so we'd get a clash. With partial unboxing, "Meter" in
> the
> > value class itself would not be erased.
> > However, this irregularity leads to surprising bridge methods which are
> not
> > working correctly. That was Pavel's example (which I append below).
> > Now, I would argue that the scheme is too limiting anyway, and that there
> > exist more robust ways to avoid name clashes.
> ...
> > So, I am for removing this special case.
> > What do people think?
> +1
> Given that value classes currently exist primarily to avoid boxing I
> support removing this feature, especially since it seems to add a lot
> of complexity to the implementation. Users of value classes shouldn't
> expect them to work like normal types in these cases.
On Wed, Sep 19, 2012 at 10:15 AM, martin odersky <martin.oder...@epfl.ch> wrote:
> With that pull-request we are currently good again: I see no more
> outstanding critical bugs against value classes, except that we have to fix
> the Java generic signatures. That should also be simpler now because erasure
> got more regular.
I opened that yesterday, but it probably is not done.
> that eliminates halfboxing. Several reported bugs disappeared: Mark's last
> variant of 3667, 3685 as well as Pavel's counter-examples on this list. So
> this looks like a definite win.
> With that pull-request we are currently good again: I see no more
> outstanding critical bugs against value classes, except that we have to fix
> the Java generic signatures. That should also be simpler now because
> erasure got more regular.
I think this is correct, except I believe the lazy val problem is still open:
I spent a fair amount of space on concrete examples of limitations as well as when allocations occur. I'd appreciate corrections for the allocations section, additions to the introduction, additional examples of limitations, or just pointing out important omissions to the list. I considered adding a section explicitly listing features they should interact ok with, like type parameters, case classes, and implicit classes. Would that be useful?
I mention that the SIP is the definitive reference for implementation details, but the SIP is actually rather out of date.
Finally, I think there needs to be an annotation @allocationBehavior(silent | warn | error) for value classes and maybe a @allowAllocation to override warnings/errors at a usage site. It is difficult to know when allocations occur from first principles or just reading the code and javap is really the only reliable way.
> On Wed, Sep 19, 2012 at 4:57 PM, Erik Osheim <e...@plastic-idolatry.com>wrote:
> > On Wed, Sep 19, 2012 at 11:20:08AM +0200, martin odersky wrote:
> > > I now also think that the "partial unboxing" which was done to allow
> > > overloading in value classes is more trouble than it's worth.
> > ...
> > > With complete unboxing both erased signatures of "/" would be
> > > (Double)Double, so we'd get a clash. With partial unboxing, "Meter" in
> > the
> > > value class itself would not be erased.
> > > However, this irregularity leads to surprising bridge methods which are
> > not
> > > working correctly. That was Pavel's example (which I append below).
> > > Now, I would argue that the scheme is too limiting anyway, and that there
> > > exist more robust ways to avoid name clashes.
> > ...
> > > So, I am for removing this special case.
> > > What do people think?
> > +1
> > Given that value classes currently exist primarily to avoid boxing I
> > support removing this feature, especially since it seems to add a lot
> > of complexity to the implementation. Users of value classes shouldn't
> > expect them to work like normal types in these cases.