According to the Scala Language specification, packages are AnyRef values and have types. How does it make sense?
I am reading the Scala Language specification and I have come across something confusing, namely, packages are assumed to be values and they have types .
This is how I concluded (perhaps wrongly?) This strange fact from the Scala Language Specification:
Background:
The type description section says:
SimpleType :: = StableId
Type notation refers to the named value type. He can be simple or skilled. All such type designations are abbreviations for projection types.
In particular, an unqualified type name t, where t is associated in some class, object, or C is taken as a shorthand for C.this.type # t . If t is not associated in a class, object, or package, then t is taken as the shorthand for ε.type # t.
The designated cool pointer is pt, where p is the path and t is the type name. This type pointer is equivalent to the projection p.type # t.
Some of the types and their extensions are listed below. We accept a local type parameter t, a value with type Node and the standard class scala.Int,
Also, considering the design type :
SimpleType :: = SimpleType '# id
The projection-type T # x refers to a member of the type named x of type T .
Finally, the definition of singleton type says:
SimpleType :: = Path '. a type
The singleton type is p.type, where p is a path that points to the value that is expected to match scala.AnyRef. Type denotes a set of values consisting of zero and a value denoted by p.
The line of reasoning:
So, we know that:
1) scala
in scala.Int
is a package.
2) scala.Int
is just syntactic sugar for scala.type#Int
(as described in the type pointer definition and shown in the picture above)
3) scala.type#Int
is a type projection, where it scala.type
should be a type according to the definition of a type projection , which says:
The projection of type T # x refers to a type member named x of type T.
4) So is a type ! Namely, it is a singleton type, according to the definition of singleton types , which says: scala.type
The singleton type is p.type, where p is a path that points to the value that scala.AnyRef should match.
5) scala
matches p
, which is the value that matches AnyRef
6) The Scala Language Specification says here that:
Every value in Scala has a type ...
7) Thus, the package scala
is of type.
Questions
1) Is this reasoning correct? Is the packet scala
really the value that matches AnyRef? If this reasoning is wrong, please explain why.
Assuming the above reasoning is correct and the package is scala
indeed the value:
2) In what sense scala
does the package matter? How does it make sense? In what context can we think of scala
as a value the same way we think of 5:Int
as a value 5
with a type Int
?
3) If the package scala
is a value that matches AnyRef, then I should be able to insert that value into a variable, can I do that, if not, why?
4) What is the meaning of the package scala
presented internally (by the compiler) behind the scenes? Is it an object? Is this value present at runtime as a JVM object? If so, how can I hold it back? How can I call a method toString
on it?
source to share
Based on experimentation, not spec:
1) packages have types, but they match Any
, not AnyRef
. You cannot assign them to type
s:
scala> type t = java.type
<console>:7: error: type mismatch;
found : java.type
required: AnyRef
Note that java extends Any, not AnyRef.
Such types can participate in value classes, but instances
cannot appear in singleton types or in reference comparisons.
Interestingly, this is not a general constraint on types Any
:
scala> type q = Int
defined type alias q
I suspect something else is going on
2) I suspect the only reason this is in the spec is for package object
s support . If we write
package object foo {
val x = 5
val y = this
}
then it would be strange to say what is foo
not a meaning (and especially strange to say what is y
not a meaning). And if a regular packet magically sprouted a value as soon as we defined for it package object
, that would be strange too.
3) I don't see any way to do this because I don't see any way to access the value. The error even says the package is not a value:
val f = foo
test.scala:10: package foo is not a value
Could it be that the value foo
"exists" in some sense, but there is no way to name it in the source (other than the package object itself)?
source to share