- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
private[this] on type declaration hides variance problem
Wed, 2009-02-25, 20:58
While exploring the variance issues in my previous post, I came across
the following variation on the Cell example in the book:
// This compiles, but not without private[this]
scala> class Cell[+A](init: A) {
| private[this] type T = A
| var x: T = init
| def set(y: T) { x = y }
| def get = x
| }
defined class Cell
// But it has the same problem as the original Cell example
scala> val c1 = new Cell[String]("abc")
c1: Cell[String] = Cell@62ad0d
scala> val c2: Cell[Any] = c1
c2: Cell[Any] = Cell@62ad0d
scala> c2.set(1)
scala> val s: String = c1.get
java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.lang.String
at .(:6)
at .()
at RequestResult$.(:3)
at RequestResult$.()
at RequestResult$result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.refl...
Should adding private[this] to the type declaration be having this effect?
Avi
Wed, 2009-02-25, 21:47
#2
Re: private[this] on type declaration hides variance problem
On Wed, Feb 25, 2009 at 02:56:27PM -0500, Avi Pfeffer wrote:
> scala> val s: String = c1.get
> java.lang.ClassCastException: java.lang.Integer cannot be cast to
> java.lang.String
Oh, I think you've got a good one there. I think someone is supposed to climb a very tall tower and ring a church bell a few
times when you find a type soundness hole like that.
Wed, 2009-02-25, 22:47
#3
Re: private[this] on type declaration hides variance problem
On Wed, Feb 25, 2009 at 7:56 PM, Avi Pfeffer wrote:
> Should adding private[this] to the type declaration be having this effect?
Very definitely not ...
Cheers,
Miles
Wed, 2009-02-25, 22:57
#4
Re: private[this] on type declaration hides variance problem
Yep, that looks like a type soundness hole. Clearly, the private[this]
exception should apply only to term members, not type types.
We'll fix it in the next release.
Cheers
Wed, 2009-02-25, 23:17
#5
Re: private[this] on type declaration hides variance problem
On Wed, Feb 25, 2009 at 9:53 PM, martin odersky <martin.odersky@epfl.ch> wrote:
So, my expectation is that what should happen here is that you'd get a warning "Private type T escapes its scope" in exactly the same way you would if you defined a private class and used it in method signatures.
i.e. the problem is not that the private[this] type T is allowed in this case, but that it can be referred to in signatures which are *not* private[this]. Does this seem reasonable?
I don't have a particular use case for it, but it seems like forbidding the type definition here would be a shame if soundness can be preserved without doing so.
I thought Scala didn't have type types? ;-)
Yep, that looks like a type soundness hole. Clearly, the private[this]
exception should apply only to term members,
So, my expectation is that what should happen here is that you'd get a warning "Private type T escapes its scope" in exactly the same way you would if you defined a private class and used it in method signatures.
i.e. the problem is not that the private[this] type T is allowed in this case, but that it can be referred to in signatures which are *not* private[this]. Does this seem reasonable?
I don't have a particular use case for it, but it seems like forbidding the type definition here would be a shame if soundness can be preserved without doing so.
not type types.
I thought Scala didn't have type types? ;-)
Wed, 2009-02-25, 23:57
#6
Re: private[this] on type declaration hides variance problem
David R. MacIver wrote:
> I thought Scala didn't have type types? ;-)
Scala has no type type types, but type types are OK. Well, as long as you
don't use private[this] :-)
Cheers,
Daniel
Thu, 2009-02-26, 01:57
#7
Re: private[this] on type declaration hides variance problem
I would suggest disallowing private[this] on types. It seems to be
exactly the same as private, but looks different.
Alternatively, make private[this] types not be allowed to be arguments
or return types of non-private[this] methods. The private[this]
exception would then be safe.
Avi
On Wed, Feb 25, 2009 at 5:12 PM, David MacIver wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
> I don't have a particular use case for it, but it seems like forbidding the
> type definition here would be a shame if soundness can be preserved without
> doing so.
>
>
>>
>> not type types.
>
> I thought Scala didn't have type types? ;-)
>
>
Thu, 2009-02-26, 08:27
#8
Re: private[this] on type declaration hides variance problem
On Thu, Feb 26, 2009 at 12:50 AM, Avi Pfeffer <avi@eecs.harvard.edu> wrote:
Indeed. Exactly the same as private, but looks different and behaves different.
Isn't that what I just said?
I would suggest disallowing private[this] on types. It seems to be
exactly the same as private, but looks different.
Indeed. Exactly the same as private, but looks different and behaves different.
Alternatively, make private[this] types not be allowed to be arguments
or return types of non-private[this] methods. The private[this]
exception would then be safe.
Isn't that what I just said?
Thu, 2009-02-26, 09:57
#9
Re: private[this] on type declaration hides variance problem
On Wed, Feb 25, 2009 at 11:12 PM, David MacIver wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
That would also be reasonable. It looks like it's higher overhead to
specify and implement this, but it would be a tad more general. I
think either of the three proposed solutions would do really.
Cheers
Thu, 2009-02-26, 11:27
#10
Re: private[this] on type declaration hides variance problem
On Thu, Feb 26, 2009 at 8:48 AM, martin odersky <martin.odersky@epfl.ch> wrote:
My assumption was that it could just inherit the following behaviour:
scala> class Foo{
| private class Bar;
| def bar = new Bar;
| }
<console>:6: error: private class Bar escapes its defining scope as part of type Foo.this.Bar
def bar = new Bar;
But actually I can't find where in the spec this behaviour is defined!
Agreed. It doesn't matter that much. This just seems mildly the more pleasant of the alternatives.
On Wed, Feb 25, 2009 at 11:12 PM, David MacIver <david.maciver@gmail.com> wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky <martin.odersky@epfl.ch>
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
That would also be reasonable. It looks like it's higher overhead to
specify and implement this, but it would be a tad more general. I
My assumption was that it could just inherit the following behaviour:
scala> class Foo{
| private class Bar;
| def bar = new Bar;
| }
<console>:6: error: private class Bar escapes its defining scope as part of type Foo.this.Bar
def bar = new Bar;
But actually I can't find where in the spec this behaviour is defined!
think either of the three proposed solutions would do really.
Agreed. It doesn't matter that much. This just seems mildly the more pleasant of the alternatives.
Fri, 2009-02-27, 13:27
#11
Re: private[this] on type declaration hides variance problem
On Thu, Feb 26, 2009 at 11:14 AM, David MacIver wrote:
> On Thu, Feb 26, 2009 at 8:48 AM, martin odersky
> wrote:
>>
>> On Wed, Feb 25, 2009 at 11:12 PM, David MacIver
>> wrote:
>> > On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
>> > wrote:
>> >>
>> >> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> >> exception should apply only to term members,
>> >
>> > So, my expectation is that what should happen here is that you'd get a
>> > warning "Private type T escapes its scope" in exactly the same way you
>> > would
>> > if you defined a private class and used it in method signatures.
>> >
>> > i.e. the problem is not that the private[this] type T is allowed in this
>> > case, but that it can be referred to in signatures which are *not*
>> > private[this]. Does this seem reasonable?
>> >
>> That would also be reasonable. It looks like it's higher overhead to
>> specify and implement this, but it would be a tad more general. I
>
> My assumption was that it could just inherit the following behaviour:
>
> scala> class Foo{
> | private class Bar;
> | def bar = new Bar;
> | }
> :6: error: private class Bar escapes its defining scope as part of
> type Foo.this.Bar
> def bar = new Bar;
>
> But actually I can't find where in the spec this behaviour is defined!
>
I think you are right. This is missing. However, the variance check
for private[this] members is specified correctly. It reads:
References to the type parameters in object-private values, variables,
or methods of the class are not checked for their variance position.
In these members the type parameter may appear anywhere without
restricting its legal variance annotations.
So Avi's discovery is a compiler bug, not a spec hole.
I have fixed it in my private version and will check this in if there
are no objections.
Cheers
The Scala Book explains something about variance and object private data in
19.7 Object private data
......
"It turns out that accesses
to variables from the same object in which they are defined do not
cause problems with variance."
......
On Wed, Feb 25, 2009 at 8:56 PM, Avi Pfeffer <avi@eecs.harvard.edu> wrote:
--
__~O
-\ <,
(*)/ (*)
reality goes far beyond imagination