- object becomes module
- package becomes module
- package object becomes module
- Support for top-level definitions
package com.foo
becomes
module com.foo
package com.foo
object bar {
def x = 1
}
becomes
module com.foo
module bar {
def x = 1
}
which is the same as
module com.foo.bar
def x = 1
package com.foo
package object bar {
val x = 42
object Y {
def z = "hello"
}
}
becomes
module com.foo.bar
val x = 42
module Y {
def z = "hello"
}
Symbols defined implicit are not allowed as top-level definitions. This is a logical restriction to make implicit symbols easier to locate in source-code. If a module is to define implicit symbols they need to be explicitly wrapped in a sealed module definition:
module com.foo
[sealed] module bar extends Implicits with MoreImplicits {
val x = 42
module Y {
def z = "hello"
}
}
This corresponds to the current solution:
package com.foo
package object bar extends Implicits with MoreImplicits{
val x = 42
object Y {
def z = "hello"
}
}
The path of a module corresponds to a standard Java-path.
Modules are, from a user-perspective, first-class: every part of a module path can be treated as an instance and passed around.
Where com.foo.bar
is a module (as in, not a class), com.foo.bar.type
is the type of the module.
Sealed modules are unique on the class-path: Classes, traits and other module paths can be defined from the path of a sealed module, but not top-level definitions.
Only sealed modules can extend traits or classes. The sealed-keyword is optional for modules that inherit from other types.
These are allowed:
File1:
module foo
sealed module bar {}
File2:
module foo.bar
class Baz
File3:
module foo.bar.baz
def main( args: Array[String] ): Unit =
println( "Hello, World!" )
These are not allowed and result in a compilation error:
File1:
module foo
sealed module bar {}
File2:
module foo.bar
val number = 42 // Error: can't add top-level definitions to a sealed module
Source structure are compiled mostly like they are today, with a few caveats.
module com.foo
trait Bar
class Baz extends Bar
yields the corresponding pseudo-definitions in bytecode
package com.foo
interface Bar
public class Baz implements Bar{}
Sealed modules compile to a module-path and a singleton:
module foo
sealed module bar {
class Baz
}
becomes
package foo.bar
public class bar$MODULE {
public static final bar$MODULE instance = …
public class Baz {}
}
Top-level definitions are unified in a deferred compilation stage to allow additional definitions after an application has been packaged. This corresponds to adding new types under an existing (third party) package.
Nominal collision rules apply: it is not possible to declare two methods foo
under the same module path but in different files. Overloading of top-level definitions is allowed in the context of one compilation unit but disallowed anywhere else.