Skip to content

Commit 6e07688

Browse files
committed
Change doc pages
- Instead of "Dropped: package objects" have a new doc page "Toplevel Definitions" in "other new features". - Add a doc page for experimental reference-able package object, which uses some wording from the Pre-SIP.
1 parent 0e03a0d commit 6e07688

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
layout: doc-page
3+
title: "Reference-able Package Objects"
4+
redirectFrom: /docs/reference/experimental/package-object-values.html
5+
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/package-object-values.html
6+
---
7+
8+
One limitation with `package object`s is that we cannot currently assign them to values: `a.b` fails to compile when `b` is a `package object`, even though it succeeds when `b` is a normal `object`. The workaround is to call
9+
```scala
10+
a.b.`package`
11+
```
12+
But this is ugly and non-obvious. Or one could use a normal `object`, which is not always possible.
13+
14+
The `packageObjectValues` language extension drops this limitation. The extension is enabled by the language import `import scala.language.experimental.packageObjectValues` or by setting the command line option `-language:experimental.packageObjectValues`.
15+
16+
The extension, turns the following into valid code:
17+
18+
```scala
19+
package a
20+
package object b
21+
22+
val z = a.b // Currently fails with "package is not a value"
23+
```
24+
25+
Currently the workaround is to use a `.package` suffix:
26+
27+
```scala
28+
val z = a.b.`package`
29+
```
30+
31+
With the extension, a reference such as `a.b` where `b` is a `package` containing a `package object`, expands to `a.b.package` automatically
32+
33+
## Limitations
34+
35+
* `a.b` only expands to `a.b.package` when used "standalone", i.e. not when part of a larger select chain `a.b.c` or equivalent postfix expression `a.b c`, prefix expression `!a.b`, or infix expression `a.b c d`.
36+
37+
* `a.b` expands to `a.b.package` of the type `a.b.package.type`, and only contains the contents of the `package object`. It does not contain other things in the `package` `a.b` that are outside of the `package object`
38+
39+
Both these requirements are necessary for backwards compatibility, and anyway do not impact the main goal of removing the irregularity between `package object`s and normal `object`s.
40+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
layout: doc-page
3+
title: "Toplevel Definitions"
4+
nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/toplevel-definitions.html
5+
---
6+
7+
All kind of definitions can now be written at the top-level.
8+
Example:
9+
```scala
10+
package p
11+
type Labelled[T] = (String, T)
12+
val a: Labelled[Int] = ("count", 1)
13+
def b = a._2
14+
15+
case class C()
16+
17+
extension (x: C) def pair(y: C) = (x, y)
18+
```
19+
Previously, `type`, `val` or `def` definitions had to be wrapped in a package object. Now,
20+
there may be several source files in a package containing such top-level definitions, and source files can freely mix top-level value, method, and type definitions with classes and objects.
21+
22+
The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories:
23+
24+
- all pattern, value, method, and type definitions,
25+
- implicit classes and objects,
26+
- companion objects of opaque type aliases.
27+
28+
If a source file `src.scala` contains such top-level definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package. The synthetic object will be placed last in the file,
29+
after any other package clauses, imports, or object and class definitions.
30+
31+
**Note:** This means that
32+
1. The name of a source file containing wrapped top-level definitions is relevant for binary compatibility. If the name changes, so does the name of the generated object and its class.
33+
34+
2. A top-level main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears
35+
in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the
36+
"program name" is mangled it is recommended to always put `main` methods in explicitly named objects.
37+
38+
3. The notion of `private` is independent of whether a definition is wrapped or not. A `private` top-level definition is always visible from everywhere in the enclosing package.
39+
40+
4. If several top-level definitions are overloaded variants with the same name,
41+
they must all come from the same source file.

Diff for: docs/sidebar.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ subsection:
123123
- page: reference/dropped-features/type-projection.md
124124
- page: reference/dropped-features/do-while.md
125125
- page: reference/dropped-features/procedure-syntax.md
126-
- page: reference/dropped-features/package-objects.md
127126
- page: reference/dropped-features/early-initializers.md
128127
- page: reference/dropped-features/class-shadowing.md
129128
- page: reference/dropped-features/class-shadowing-spec.md
@@ -164,6 +163,7 @@ subsection:
164163
- page: reference/experimental/runtimeChecked.md
165164
- page: reference/experimental/better-fors.md
166165
- page: reference/experimental/unrolled-defs.md
166+
- page: reference/experimental/package-object-values.md
167167
- page: reference/syntax.md
168168
- title: Language Versions
169169
index: reference/language-versions/language-versions.md

0 commit comments

Comments
 (0)