Skip to content

Commit bc01d82

Browse files
committed
Reorder new features. Acknowledge named tuples as experimental and encourage to test it out in notable changes section
1 parent d00dabb commit bc01d82

File tree

1 file changed

+70
-65
lines changed

1 file changed

+70
-65
lines changed

_posts/2024-12-05-release-notes-3.6.2.md

Lines changed: 70 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,71 +24,6 @@ trait DB {
2424
}
2525
```
2626

27-
## SIP-58 - Named Tuples
28-
29-
Another stabilized feature in this release are the Named Tuples. These have been introduced as experimental in Scala 3.5.0 and allowed you to give meaningful names to tuple elements and use those names during constructing, destructuring, and pattern matching.
30-
31-
```scala
32-
extension [T](seq: Seq[T])
33-
def partitionBy(predicate: PartialFunction[T, Boolean]): (matching: Seq[T], unmatched: Seq[T]) =
34-
seq.partition(predicate.unapply(_).isDefined)
35-
36-
@main def onlySmallRealNumbers =
37-
List(
38-
(x = 1, y = 0),
39-
(x = 2, y = 3),
40-
(x = 0, y = 1),
41-
(x = 3, y = 0),
42-
).partitionBy:
43-
case (x = real, y = 0) => real < 5
44-
.matching.map(_.x)
45-
.foreach(println)
46-
```
47-
48-
This change also introduces improvements to extractors of case classes. You can now define named extractors for a selection of fields, allowing you to unclutter your code from unused variables.
49-
50-
```scala
51-
case class User(id: Int, name: String, surname: String)
52-
53-
extension (values: Seq[User])
54-
// Collect user IDs of every entry that has the name matching argument
55-
def idsWithName(name: String) = values.collect:
56-
case User(name = `name`, id = userId) => userId
57-
```
58-
59-
Last, but not least, named tuples are opening a new paradigm of metaprogramming by letting you compute structural types without need for macros!
60-
The `Selectable` trait now has a `Fields` type member that can be instantiated to a named tuple.
61-
62-
```scala
63-
class QueryResult[T](rawValues: Map[String, Any]) extends Selectable:
64-
type Fields = NamedTuple.Map[NamedTuple.From[T], Option]
65-
def selectDynamic(fieldName: String) = rawValues.get(fieldName)
66-
67-
case class City(zipCode: Int, name: String)
68-
69-
@main def Test =
70-
val query: QueryResult[City] = QueryResult(Map("name" -> "Lausanne"))
71-
assert(query.name.contains("Lausanne"))
72-
assert(query.zipCode.isEmpty)
73-
```
74-
75-
You can read more about named tuples in the [dedicated section of Scala 3 reference documentation](https://scala-lang.org/api/3.6.2/docs/docs/reference/other-new-features/named-tuples.html).
76-
77-
## SIP-62 - For-Comprehension Improvements
78-
79-
Starting with Scala 3.6.2 you can take advantage of improvements to the for-comprehesnions syntax.
80-
Major user-facing improvement introduced by [SIP-62](https://docs.scala-lang.org/sips/better-fors.html) is the ability to start a for-comprehension block with aliases:
81-
82-
```scala
83-
for
84-
a = 1
85-
b <- Some(2)
86-
c <- doSth(a)
87-
yield b + c
88-
```
89-
90-
It also introduces changes to how your code is desugared by the compiler, leading to a more optimized code by removing some redundant calls.
91-
9227
## SIP-64 - Improve Syntax for Context Bounds and Givens
9328

9429
This release stabilises the [SIP-64](https://docs.scala-lang.org/sips/sips/typeclasses-syntax.html) introduced as experimental in Scala 3.5.0. These changes provide you with the new syntax for defining type class instances.
@@ -170,6 +105,21 @@ type InvF[Y] = Y match
170105
def Test = summon[InvF[B] =:= String] // was error: selector B does not uniquely determine parameter x
171106
```
172107

108+
## Experimental SIP-62 - For-Comprehension Improvements
109+
110+
Starting with Scala 3.6.2 you can take advantage of improvements to the for-comprehesnions syntax.
111+
Major user-facing improvement introduced by [SIP-62](https://docs.scala-lang.org/sips/better-fors.html) is the ability to start a for-comprehension block with aliases:
112+
113+
```scala
114+
for
115+
a = 1
116+
b <- Some(2)
117+
c <- doSth(a)
118+
yield b + c
119+
```
120+
121+
It also introduces changes to how your code is desugared by the compiler, leading to a more optimized code by removing some redundant calls.
122+
173123
## Experimental SIP-57 - Replace non-sensical `@unchecked` annotations
174124

175125
One of the new, experimental, features is the implementation of [SIP-57](https://docs.scala-lang.org/sips/replace-nonsensical-unchecked-annotation.html) introducing a `runtimeChecked` extension method replacing some usages of `@unchecked` annotation using a more convenient syntax. A common use case for `runtimeChecked` is to assert that a pattern will always match, either for convenience or because there is a known invariant that the types can not express.
@@ -220,6 +170,61 @@ Reordering the fields is binary-compatible but it might affect the meaning of `@
220170
Starting from Scala 3.6, named arguments are required for Java-defined annotations.
221171
The compiler can provide you with automatic rewrites introducing now required names, using `-source:3.6-migration, -rewrite` flags. The rewrites are done on a best-effort basis and should be inspected for correctness by the users.
222172

173+
## Experimental SIP-58 - Named Tuples
174+
175+
Named Tuples have been introduced as experimental in Scala 3.5.0. This feature is now ready to be tested, but is not yet stablized.
176+
We encourage you to try named tuples and to report your feedback [on the public forum](https://contributors.scala-lang.org/t/pre-sip-named-tuples).
177+
Named Tuples allow you to give meaningful names to tuple elements and use those names during constructing, destructuring, and pattern matching.
178+
179+
```scala
180+
//> using options -experimental -language:experimental.namedTuples
181+
extension [T](seq: Seq[T])
182+
def partitionBy(predicate: PartialFunction[T, Boolean]): (matching: Seq[T], unmatched: Seq[T]) =
183+
seq.partition(predicate.unapply(_).isDefined)
184+
185+
@main def onlySmallRealNumbers =
186+
List(
187+
(x = 1, y = 0),
188+
(x = 2, y = 3),
189+
(x = 0, y = 1),
190+
(x = 3, y = 0),
191+
).partitionBy:
192+
case (x = real, y = 0) => real < 5
193+
.matching.map(_.x)
194+
.foreach(println)
195+
```
196+
197+
This change also introduces improvements to extractors of case classes. You can now define named extractors for a selection of fields, allowing you to unclutter your code from unused variables.
198+
199+
```scala
200+
//> using options -experimental -language:experimental.namedTuples
201+
case class User(id: Int, name: String, surname: String)
202+
203+
extension (values: Seq[User])
204+
// Collect user IDs of every entry that has the name matching argument
205+
def idsWithName(name: String) = values.collect:
206+
case User(name = `name`, id = userId) => userId
207+
```
208+
209+
Last, but not least, named tuples are opening a new paradigm of metaprogramming by letting you compute structural types without need for macros!
210+
The `Selectable` trait now has a `Fields` type member that can be instantiated to a named tuple.
211+
212+
```scala
213+
//> using options -experimental -language:experimental.namedTuples
214+
class QueryResult[T](rawValues: Map[String, Any]) extends Selectable:
215+
type Fields = NamedTuple.Map[NamedTuple.From[T], Option]
216+
def selectDynamic(fieldName: String) = rawValues.get(fieldName)
217+
218+
case class City(zipCode: Int, name: String)
219+
220+
@main def Test =
221+
val query: QueryResult[City] = QueryResult(Map("name" -> "Lausanne"))
222+
assert(query.name.contains("Lausanne"))
223+
assert(query.zipCode.isEmpty)
224+
```
225+
226+
You can read more about named tuples in the [dedicated section of Scala 3 reference documentation](https://scala-lang.org/api/3.6.2/docs/docs/reference/experimental/named-tuples.html).
227+
223228
# What’s next?
224229
<!-- TODO: Fill me -->
225230

0 commit comments

Comments
 (0)