Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport "Fix #20271: Bring for comprehension spec up to date." to 3.6.2 #21900

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/_spec/06-expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -729,16 +729,17 @@ A _for loop_ `for (´\mathit{enums}\,´) ´e´` executes expression ´e´ for ea
A _for comprehension_ `for (´\mathit{enums}\,´) yield ´e´` evaluates expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´ and collects the results.
An enumerator sequence always starts with a generator; this can be followed by further generators, value definitions, or guards.

A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is matched in some way against pattern ´p´.
Optionally, `case` can appear in front of a generator pattern, this has no meaning in Scala 2 but will be [required in Scala 3 if `p` is not irrefutable](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html).
A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is deconstructed by the pattern ´p´.
The pattern must be [irrefutable](08-pattern-matching.html#irrefutable-patterns).
A _conditional generator_ `case ´p´ <- ´e´` tests whether elements produced by ´e´ match the pattern and discards the ones that do not match.

A _value definition_ `´p´ = ´e´` binds the value name ´p´ (or several names in a pattern ´p´) to the result of evaluating the expression ´e´.
A _guard_ `if ´e´` contains a boolean expression which restricts enumerated bindings.
The precise meaning of generators and guards is defined by translation to invocations of four methods: `map`, `withFilter`, `flatMap`, and `foreach`.
These methods can be implemented in different ways for different carrier types.

The translation scheme is as follows.
In a first step, every generator `´p´ <- ´e´`, where ´p´ is not [irrefutable](08-pattern-matching.html#patterns) for the type of ´e´ is replaced by
In a first step, every generator `case ´p´ <- ´e´` is replaced by

```scala
´p´ <- ´e´.withFilter { case ´p´ => true; case _ => false }
Expand Down Expand Up @@ -772,7 +773,7 @@ Then, the following rules are applied repeatedly until all comprehensions have b
´e´.foreach { case ´p´ => for (´p'´ <- ´e'; ...´) ´e''´ }
```

- A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator `´p´ <- ´e´.withFilter((´x_1, ..., x_n´) => ´g\,´)` where ´x_1, ..., x_n´ are the free variables of ´p´.
- A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator `´p´ <- ´e´.withFilter({ case ´p´ => ´g\,´ })`.

- A generator `´p´ <- ´e´` followed by a value definition `´p'´ = ´e'´` is translated to the following generator of pairs of values, where ´x´ and ´x'´ are fresh names:

Expand Down