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,

enter image description here

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?

+3


source to share


1 answer


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)?

+5


source







All Articles