Obviously I can't comment on the lateness in the release cycle.
Yeah, we would really profit from checklists for both code and SIP
review. Top of the list: interaction with existing features.
The current compilation scheme for methods that accept Value Class
parameters doesn't play nicely with reflection, structural types, or
callers from Java. SI-6336 details the issues [1]. In the comments, I
propose an alternative.
I know it's very late in the release cycle, but we ought to discuss:
- Is the alternative proposal feasible?
- For how long can we live with the current limitations?
- Can we at least turn some of those limitations into compile,
rather than runtime, errors?
- What's the migration path to the alternative? I feel it would be
messy to change in a minor release.
I couldn't find any discussion of this particular detail on the list;
most of the discussions on this SIP gravitated to FlatArray, and the
overall attention on the list might have been spread too thinly across
the smorgasbord of SIPs on offer at the time (I'm looking at you, 18.)
-jason
[1] https://issues.scala-lang.org/browse/SI-6336
On Mon, Sep 10, 2012 at 9:37 AM, martin odersky <martin....@epfl.ch> wrote:The boxed bridge method would both unbox parameters and box results.
> I don't know. The proposal only deals with method parameters, what about
> results? There are many other places where value classes come into the mix
> and we'd have to be sure we deal with them all. My preference in this case
> would be to have as simple a semantic model as possible.
> The current model is: Value classes erase to the same type as theirYep, Structural Types and Scala reflection both have enough
> underlying type.
>
> I think we can keep to it and address the concerns:
>
> - structural types: Have a restriction that method signatures in structural
> types may not refer to value classes. We already have a restriction that
> they may not refer to enclosing class parameters, so this is nothing new. At
> some point we might want to come back and change the structural type
> dispatch scheme, which could then hopefully get rid of both restrictions in
> one fell sweep.
>
> - reflection: not sure yet, but I guess we can find the right rules. In any
> case, I vote for keeping reflection experimental for the current release so
> we have time to fix it.
information to do the Right Thing, eventually. But I think it's
tempting to install unboxed bridges to avoid touching either of them.
Or declare Value Classes experimental?
> - Java interop: Have the simple rule that value classes are invisible for
> Java. Java APIs have to deal with the underlying type instead. This is good,
> in my opinion. The whole purpose of value classes is to give nice syntactic
> coating for something that does not need boxing. Having to box from Java is
> not an improvement, IMO.
They also offer type safety. One Java caller might prefer convenience
+ type safety, another might prefer performance. I don't think we can
say one need is greater than the other.
But if that's the goal, it really needs to be explicitly stated, and
well tested. The erasure transformation should also be applied to the
generic signatures; I suspect Eclipse will choke on what is currently
emitted (can someone knowledgeable test this please?):
scala> class Val[A](val value: Int) extends AnyVal
defined class Val
scala> class C2 { def foo[A](in: Val[A]) = in }
defined class C2
scala> classOf[C2].getMethods.head
res4: java.lang.reflect.Method = public int C2.foo(int)
scala> res4.getGenericParameterTypes
res5: Array[java.lang.reflect.Type] = Array(.Val<A>)
With a bit of work, IntelliJ can be made to expose the right
signatures to Java; it doesn't use the generic signatures.
I'd favour the walk-before-we-run approach here.
> Regarding time frame: I think the fixes for value classes can be done this
> week or next at the outset. Redoing the design will add at least one or two
> months to the release schedule. I think our time is better spent on
> extending value classes to multiple parameters.
On Mon, Sep 10, 2012 at 11:08 AM, martin odersky <martin....@epfl.ch> wrote:Good questions, I don't have answers just yet.
>> The boxed bridge method would both unbox parameters and box results.
>>
> I see. How about fields? I assume you'd do the same thing for getters and
> setters, right? Next question: How do $unboxed variants relate to
> overrriding?
Without giving it full thought, I think it would be +1 rather than *2;
> By now I fear getting another exponent of interaction with other bridge
> methods (overriding bridges, specialized variants). I would not want to do
> that before we had a careful look at specialization of value classes. And
> that's many months away, at best. (E.g. if the proposal means that we get
> another doubling of specialized methods, it won't fly).
the unboxed bridge should invoke the unspecialized bridge.
It borrows a nice idea from specialization, but I don't think it --
> Generally, $unboxed methods are very similar to specialized methods. We know
> that specialized is a rats nest of complexity. What kind of arguments do we
> have that could convince us that this proposal will not lead to the same
> problems?
we're not creating new subclasses. Conceptually, one could add all
these unboxed bridges as a post-processing step after the current
scheme as run. (assuming you can live with the unboxed and boxes
methods both having the same original name.)
-jason
Of course, the generic signatures have to be adapted. That's critical!I would classify this as a blocker. Somebody please file a ticket or this. Who could have a look at this? Paul?
By the way, why there are all these methods in Foo$.MODULE$ ?
I believe it's better to generate code right in static methods in Foo.class.
This way calling value class methods may be somewhat more efficient.
class Box[X](val x: X) extends AnyVal { def map[Y](f: X => Y): Box[Y] = ((bx: Box[X]) => new Box(f(bx.x)))
(this)
}
new Box(42) map (_ + 1)
In fact, SIP-15 as discussed and accepted did not allow this case; it was added later. (I believe to make ArrowAssoc work as a value class, are there other cases where we need it in the libraries right now?)
class V[T](xs: List[T])should still work, even though it is parameterized. Throwing out the latter would render value classes next to useless.
I was thinking mostly of implicit wrappers, which all tend to be parametric. - Martin
I believe the right way to solve the problem is to mangle method names which have value class arguments/results.
This way we can cure SI-6260, allow structural-value types interaction and add a bit of Java interop, all in one shot.
Unfortunately, this won't help.
On Wed, Sep 12, 2012 at 10:50 AM, Paul Phillips <pa...@improving.org> wrote:+1. This stuff can always continue to improve in 2.11 and beyond.
> I think we should/must restrict our way to a solution right now.
Better to ship a more limited feature that actually works, than
something that seems to promise the sky but is full of holes if you
look closely.
+2 on that sentiment. (*cough* specialization *cough*--I wasted way too much time trying to work around all the bugs there)
Note that we are talking about the bridge for the _apply_ method of Function1. I do not see how that name could be mangled.On Wed, Sep 12, 2012 at 4:43 PM, Pavel Pavlov <pavel.e...@gmail.com> wrote:
On Wednesday, September 12, 2012 9:32:39 PM UTC+7, Pavel Pavlov wrote:I believe the right way to solve the problem is to mangle method names which have value class arguments/results.
This way we can cure SI-6260, allow structural-value types interaction and add a bit of Java interop, all in one shot.
I mean that signature of `def foo(x: VC)` should not be touched, the method should be converted to forwarder
for synthetic `def foo$vc(x: UnderlyingTypeOfVC)`
On Wed, Sep 12, 2012 at 7:43 PM, martin odersky <martin....@epfl.ch> wrote:Note that we are talking about the bridge for the _apply_ method of Function1. I do not see how that name could be mangled.On Wed, Sep 12, 2012 at 4:43 PM, Pavel Pavlov <pavel.e...@gmail.com> wrote:
On Wednesday, September 12, 2012 9:32:39 PM UTC+7, Pavel Pavlov wrote:I believe the right way to solve the problem is to mangle method names which have value class arguments/results.
This way we can cure SI-6260, allow structural-value types interaction and add a bit of Java interop, all in one shot.
I mean that signature of `def foo(x: VC)` should not be touched, the method should be converted to forwarder
for synthetic `def foo$vc(x: UnderlyingTypeOfVC)`I see now. Leave the bridge as `apply`, but rename the concrete apply method containing the Box types, I guess.
That could work. But I agree with Paul that it's too risky to introduce new name mangling for 2.10.
Cheers- Martin
That discussion notwithstanding I still think it might be wise to disallow fully parametric wrappers of formclass V[T](x: T)as they seem to be a source of several other problems and we can't claim we understand the interactions fully.
I think we need to put in another test against bridges that erase to the same type as an existing definition. In principle that's nothing new, we do have these tests, but they did not do the right thing for value classes. But now I think I know exactly what to do. Thanks for putting me on the right track!
So I still believe that mangling methods which have unboxed value class arguments/results (at least methods which overrides/implements those of superclasses/traits) is the only viable solution.
For this function "_it may be applied to an Integer_" means that call to `f` may result in returning Integer which definitely is not what we want.
By the way, keep in mind that we can overload on return type at the jvm level. So in principle all these methods can coexist if it serves our purposes:(Object)Box(Object)Integer(Object)Object
Of course, they can coexist, but how you will call them? Via reflection? Or will you generate extra interfaces declaring methods with such signatures?
) val f has type `$anon`.
On Mon, 17 Sep 2012 18:25:45 +0200There is a problem with type parameters getting messed up. See my last comment in:
martin odersky <martin....@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.
https://issues.scala-lang.org/browse/SI-6358
> OtherSee my last comment on
> problems are solved by restrictions:
>
> - no value classes in structural refinements
https://issues.scala-lang.org/browse/SI-6336
that shows the return type needs to exclude value classes as well:
Might need to include universal traits in that exclusion:
> - value classes cannot unbox to other derived value classes.
https://issues.scala-lang.org/browse/SI-6337
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.
Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn