From 4429fd1cae67ca88ed1dc6a3e7bb47902d3d65d3 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 25 Nov 2024 19:19:20 +0100 Subject: [PATCH] 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. --- .../experimental/package-object-values.md | 40 ++++++++++++++++++ .../toplevel-definitions.md | 41 +++++++++++++++++++ docs/sidebar.yml | 4 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/_docs/reference/experimental/package-object-values.md create mode 100644 docs/_docs/reference/other-new-features/toplevel-definitions.md diff --git a/docs/_docs/reference/experimental/package-object-values.md b/docs/_docs/reference/experimental/package-object-values.md new file mode 100644 index 000000000000..1ca9c701970a --- /dev/null +++ b/docs/_docs/reference/experimental/package-object-values.md @@ -0,0 +1,40 @@ +--- +layout: doc-page +title: "Reference-able Package Objects" +redirectFrom: /docs/reference/experimental/package-object-values.html +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/package-object-values.html +--- + +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 +```scala + a.b.`package` +``` +But this is ugly and non-obvious. Or one could use a normal `object`, which is not always possible. + +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`. + +The extension, turns the following into valid code: + +```scala +package a +package object b + +val z = a.b // Currently fails with "package is not a value" +``` + +Currently the workaround is to use a `.package` suffix: + +```scala +val z = a.b.`package` +``` + +With the extension, a reference such as `a.b` where `b` is a `package` containing a `package object`, expands to `a.b.package` automatically + +## Limitations + +* `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`. + +* `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` + +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. + diff --git a/docs/_docs/reference/other-new-features/toplevel-definitions.md b/docs/_docs/reference/other-new-features/toplevel-definitions.md new file mode 100644 index 000000000000..b1793bd1941c --- /dev/null +++ b/docs/_docs/reference/other-new-features/toplevel-definitions.md @@ -0,0 +1,41 @@ +--- +layout: doc-page +title: "Toplevel Definitions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/toplevel-definitions.html +--- + +All kind of definitions can now be written at the top-level. +Example: +```scala +package p +type Labelled[T] = (String, T) +val a: Labelled[Int] = ("count", 1) +def b = a._2 + +case class C() + +extension (x: C) def pair(y: C) = (x, y) +``` +Previously, `type`, `val` or `def` definitions had to be wrapped in a package object. Now, +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. + +The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories: + + - all pattern, value, method, and type definitions, + - implicit classes and objects, + - companion objects of opaque type aliases. + +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, +after any other package clauses, imports, or object and class definitions. + +**Note:** This means that +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. + +2. A top-level main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears +in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the +"program name" is mangled it is recommended to always put `main` methods in explicitly named objects. + +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. + +4. If several top-level definitions are overloaded variants with the same name, +they must all come from the same source file. diff --git a/docs/sidebar.yml b/docs/sidebar.yml index 8cae4e95725a..e5cd5a208051 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -72,6 +72,8 @@ subsection: - page: reference/other-new-features/export.md - page: reference/other-new-features/opaques.md - page: reference/other-new-features/opaques-details.md + - page: reference/other-new-features/toplevel-definitions.md + - page: reference/other-new-features/named-tuples.md - page: reference/other-new-features/open-classes.md - page: reference/other-new-features/parameter-untupling.md - page: reference/other-new-features/parameter-untupling-spec.md @@ -123,7 +125,6 @@ subsection: - page: reference/dropped-features/type-projection.md - page: reference/dropped-features/do-while.md - page: reference/dropped-features/procedure-syntax.md - - page: reference/dropped-features/package-objects.md - page: reference/dropped-features/early-initializers.md - page: reference/dropped-features/class-shadowing.md - page: reference/dropped-features/class-shadowing-spec.md @@ -164,6 +165,7 @@ subsection: - page: reference/experimental/runtimeChecked.md - page: reference/experimental/better-fors.md - page: reference/experimental/unrolled-defs.md + - page: reference/experimental/package-object-values.md - page: reference/syntax.md - title: Language Versions index: reference/language-versions/language-versions.md