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

Visibility of class parameters

6 replies
Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.

The following behavior was surprising to me and I'm wondering if it's
correct according to the language spec.

Welcome to Scala version 2.8.0.Beta1-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).

scala> class C (x: Int)
defined class C

scala> new C(5)
res0: C = C@70f16568

scala> import res0.x
:6: error: x is not a member of res0
import res0.x
^
So far so good. x is only visible within C, so the error makes sense.
But now if I actually refer to x inside C:

scala> class C (x: Int) { def foo = x }
defined class C

scala> new C(5)
res1: C = C@530f243b

scala> import res1.x
import res1.x

scala> x
:8: error: value x cannot be accessed in C
x
^

I was able to import x, even though x cannot be accessed!

I understand that because foo refers to x, internally C must now have a
field for x. But it seems surprising to me that this change would
increase the visibility of x to other code.

Is this covered in the spec? Section 5.3, Class Definitions, covers
class parameters but it doesn't talk about what happens when a class
parameter is referred to in one of the class's methods. (I can't find a
section that does talk about that.)

geoff
Joined: 2008-08-20,
User offline. Last seen 1 year 25 weeks ago.
Re: Visibility of class parameters

On Thu, Dec 03, 2009 at 03:54:14PM -0600, Seth Tisue said
> Is this covered in the spec? Section 5.3, Class Definitions, covers
> class parameters but it doesn't talk about what happens when a class
> parameter is referred to in one of the class's methods. (I can't find a
> section that does talk about that.)

I believe this is the same oddity discussed in
http://old.nabble.com/strange-%22reassignment-to-val%22-error-when-writi...

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Visibility of class parameters

On Thu, Dec 3, 2009 at 10:54 PM, Seth Tisue wrote:
>
> The following behavior was surprising to me and I'm wondering if it's
> correct according to the language spec.
>
> Welcome to Scala version 2.8.0.Beta1-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
>
> scala> class C (x: Int)
> defined class C
>
> scala> new C(5)
> res0: C = C@70f16568
>
> scala> import res0.x
> :6: error: x is not a member of res0
>       import res0.x
>              ^
> So far so good.  x is only visible within C, so the error makes sense.
> But now if I actually refer to x inside C:
>
> scala> class C (x: Int) { def foo = x }
> defined class C
>
> scala> new C(5)
> res1: C = C@530f243b
>
> scala> import res1.x
> import res1.x
>
> scala> x
> :8: error: value x cannot be accessed in C
>       x
>       ^
>
> I was able to import x, even though x cannot be accessed!
>
> I understand that because foo refers to x, internally C must now have a
> field for x.  But it seems surprising to me that this change would
> increase the visibility of x to other code.
>
Imports are not subject to accessibility rules. In am import
statement, no attempt is made to check whether the imported value is
accessible -- in fact we could only do a rough approximation of
accessibility anyway, because the precise rules would depend on where
and how the identifier is then referred to later.

> Is this covered in the spec?  Section 5.3, Class Definitions, covers
> class parameters but it doesn't talk about what happens when a class
> parameter is referred to in one of the class's methods.  (I can't find a
> section that does talk about that.)
>
> --
It's covered in the chapter on imports. i cite:

Import selectors work in the same way for type and term members. For
instance, an import clause ~\lstinline@import $p$.{$x$ => $y\,$}@~
renames the term
name \lstinline@$p$.$x$@ to the term name $y$ and the type name
\lstinline@$p$.$x$@
to the type name $y$. At least one of these two names must
reference a member of $p$.

Note that nothing is said about whether the member needs to be accessible.

Cjeers

geoff
Joined: 2008-08-20,
User offline. Last seen 1 year 25 weeks ago.
Re: Visibility of class parameters

On Thu, Dec 03, 2009 at 11:52:04PM +0100, martin odersky said
> > I understand that because foo refers to x, internally C must now have a
> > field for x.  But it seems surprising to me that this change would
> > increase the visibility of x to other code.
> >
> Imports are not subject to accessibility rules. In am import
> statement, no attempt is made to check whether the imported value is
> accessible -- in fact we could only do a rough approximation of
> accessibility anyway, because the precise rules would depend on where
> and how the identifier is then referred to later.

I think the issue is different from accessibility. As the identifier x
is not a member (val, var or def) of class C there should not be
anything to import regardless of accessibility. In other words, while
the java signature for the class must contain a field for x, the scala
signature should not. I.e. fields with the paramaccessor flag should not
be selectable.

Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: Visibility of class parameters

>>>>> "martin" == martin odersky writes:

martin> Note that nothing is said about whether the member needs to be
martin> accessible.

I understand that visibility and accessibility are different, and that
something can be visible without being accessible.

In this case, though, why is x visible outside C? I think it should not
be, and I can find nothing in the spec to justify x's visibility
(though, am I missing something? it wouldn't be the first time!).

As Geoff Reedy writes (thanks, Geoff, for stating this so clearly):

Geoff> I think the issue is different from accessibility. As the
Geoff> identifier x is not a member (val, var or def) of class C there
Geoff> should not be anything to import regardless of accessibility. In
Geoff> other words, while the java signature for the class must contain
Geoff> a field for x, the scala signature should not. I.e. fields with
Geoff> the paramaccessor flag should not be selectable.

geoff
Joined: 2008-08-20,
User offline. Last seen 1 year 25 weeks ago.
Re: Visibility of class parameters

On Thu, Dec 03, 2009 at 07:24:28PM -0600, Seth Tisue said
> >>>>> "martin" == martin odersky writes:
>
> martin> Note that nothing is said about whether the member needs to be
> martin> accessible.
>
> I understand that visibility and accessibility are different, and that
> something can be visible without being accessible.
>
> In this case, though, why is x visible outside C? I think it should not
> be, and I can find nothing in the spec to justify x's visibility
> (though, am I missing something? it wouldn't be the first time!).
>
> As Geoff Reedy writes (thanks, Geoff, for stating this so clearly):
>
> Geoff> I think the issue is different from accessibility. As the
> Geoff> identifier x is not a member (val, var or def) of class C there
> Geoff> should not be anything to import regardless of accessibility. In
> Geoff> other words, while the java signature for the class must contain
> Geoff> a field for x, the scala signature should not. I.e. fields with
> Geoff> the paramaccessor flag should not be selectable.

So what's the verdict? Is this a bug that should be filed?

Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: Visibility of class parameters

>>>>> "Geoff" == Geoff Reedy writes:

Geoff> So what's the verdict? Is this a bug that should be filed?

No verdict, but I filed it anyway:
http://lampsvn.epfl.ch/trac/scala/ticket/2773

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