- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
type declarations, generic signatures, and bug #1642
Wed, 2009-02-18, 18:08
All,
I am after ticket #1642, and I'd like some opinions or suggestions about
the underlying type-related matter.
The issue stems from the following; if the code contains something like
class R[F]
abstract class X[...] {
type P <: R[P]
def x:P ...
then the signature of the members that use P will be incorrect: in the
signature calculation, during normalization, P will be expanded to R[F],
where F doesn't exist in class X. As a consequence, the resulting classfile
cannot be used from Java.
Now, in the code that generates the signature there is actually a check for
type arguments with recursive bounds, leading to wildcards, but there is no
suitable check for this particular case. I can think about a few alternatives:
1) conservatively disallowing declarations like "type P<:R[P]", which
contain cyclic references. That seems restrictive, though.
2) preventing altogether the generation of signatures for those particular
members, leaving only the erased form.
3) adding a check similar to that for the type arguments, introducing
wildcards when needed. However, in the following:
def h(x:P):P = x
the Java view of the method would become "R[?] h(R[?] x)", and the
connection between the type of the argument and the type of the result
would be lost, leading to explicit casts at the call sites.
4) a further alternative is adding a surreptitious type argument to the
method signature, turning the signature of the above h into:
;>(TFresh$1;)TFresh$1;
corresponding to the Java:
> Fresh$1 h(Fresh$1 x) {...}
This would work, with the caveat that if someone in Java uses the notation
obj.meth(args)
then the number of type parameters won't match the original, and the error
message will be quite cryptic. But, yet again, explicitly specifying the
type parameters of method calls is pretty uncommon.
Any opinions/preferences/advice?
Thanks,
Toni
Fri, 2009-02-27, 23:57
#2
Re: type declarations, generic signatures, and bug #1642
On Wed, Feb 18, 2009 at 7:12 PM, David MacIver wrote:
> On Wed, Feb 18, 2009 at 5:04 PM, Antonio Cunei
> wrote:
>>
>> All,
>>
>> I am after ticket #1642, and I'd like some opinions or suggestions about
>> the underlying type-related matter.
>>
>> The issue stems from the following; if the code contains something like
>>
>> class R[F]
>> abstract class X[...] {
>> type P <: R[P]
>> def x:P ...
>>
>> then the signature of the members that use P will be incorrect: in the
>> signature calculation, during normalization, P will be expanded to R[F],
>> where F doesn't exist in class X. As a consequence, the resulting classfile
>> cannot be used from Java.
>>
> (... )
>>
>> 3) adding a check similar to that for the type arguments, introducing
>> wildcards when needed. However, in the following:
>>
>> def h(x:P):P = x
>>
>> the Java view of the method would become "R[?] h(R[?] x)", and the
>> connection between the type of the argument and the type of the result would
>> be lost, leading to explicit casts at the call sites.
>
> To me this sounds like the best option. It sounds simple and non-invasive,
> and it doesn't seem worth trying to encode Scala's type system into Java's:
> It is expected that you will lose some type safety at the Java side, because
> its type system is less expressive.
>
I also lean to (3), with (2) as a less good alternative. We certainly
can't outlaw F-bounded abstract types, nor should we produce a lot of
magic to dress them up.
Cheers
(... )
To me this sounds like the best option. It sounds simple and non-invasive, and it doesn't seem worth trying to encode Scala's type system into Java's: It is expected that you will lose some type safety at the Java side, because its type system is less expressive.