Skip to content

Commit 7e5f614

Browse files
committed
Further edits on the announcement:
- add contributors list - add named tuples section - shorten the given prioritazation section
1 parent 7f0fd24 commit 7e5f614

File tree

1 file changed

+62
-22
lines changed

1 file changed

+62
-22
lines changed

blog/_posts/2024-10-15-scala-3.5.0-released.md

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,37 +76,32 @@ assert(0B_1000_0010 == 130)
7676
assert(0B_1000_0010 == 0x82)
7777
```
7878

79-
## Work on a better scheme for given prioritization
79+
### Experimental: named tuples
8080

81-
Givens in Scala 3 have a peculiar problem with prioritization. To illustrate it, let's consider the following inheritance triangle for type classes:
81+
Scala 3.5 introduces experimental support for named tuples. The feature hidden behind the `language.experimental.namedTuples` import, allows you to give meaningful names to tuple elements and use those nemes during constructing, destructuring, and pattern matching.
8282

8383
```scala
84-
trait Functor[F[_]]:
85-
extension [A, B](x: F[A]) def map(f: A => B): F[B]
86-
trait Monad[F[_]] extends Functor[F] { ... }
87-
trait Traverse[F[_]] extends Functor[F] { ... }
88-
```
89-
90-
and corresponding instances
84+
import scala.language.experimental.namedTuples
9185

92-
```scala
93-
given Functor[List] = ???
94-
given Monad[List] = ???
95-
given Traverse[List] = ???
96-
```
86+
type Point = (x: Int, y: Int)
87+
val point: Point = (x = 1, y = 2)
88+
val is_it_point = (x = 5, y = 3)
89+
val it_is: Point = is_it_point
9790

98-
Now, let's use the instances in the following context:
91+
println(point.x) // prints 1
9992

100-
```scala
101-
def fmap[F[_] : Functor, A, B](c: F[A])(f: A => B): F[B] = c.map(f)
102-
fmap(List(1,2,3))(_.toString) // ERROR
93+
point match
94+
case (x = real, y = 0) => println(s"Real number: $real")
95+
case _ => println("Point doesn't represent a real number")
10396
```
10497

105-
The compiler will reject the above code with a message about the `Functor` context bound being ambiguous. This is unintuitive and undesired behavior. The reason for this is that `Monad` and `Traverse` types are subtypes of `Functor`, so their instances are more specific than the `Functor` instance. They, in turn, are incomparable in terms of specificity, so the result is ambiguity.
98+
This is an implementation of [SIP-58](https://github.com/scala/improvement-proposals/blob/d649f6e6f333cd9232d85a12bd0445d18a673f10/content/named-tuples.md).
10699

107-
The solution to this kind of problem is to change the scheme of given prioritization. If we decide that we are always selecting the instance with **the most general subtype** that satisfies the context bound, the above example would work as intended.
100+
## Work on a better scheme for given prioritization
101+
102+
Givens in Scala 3 have a peculiar problem with prioritization. The compiler tries to always select the instance with *the most specific subtype* of the requested type. This can lead to confusing situtaions, when user faces ambiguity errors in code that should intuitivel work. Changing the scheme of given priritization to always select the instance with *the most general subtype* that satisfies the context bound, would resolve such cases. We have conducted experiments that showed that the proposed scheme will result in a more intuitive and predictable given resolution. The negative impact on the existing projects is very small. We have tested 1500 open-source libraries, and new rules are causing problems for less than a dozen of them. We have already submitted PRs with changes that will make them work the same way under both the current and proposed rules.
108103

109-
We have conducted experiments that showed that the proposed scheme will result in a more intuitive and predictable given resolution. The negative impact on the existing projects is very small. We have tested 1500 open-source libraries, and new rules are causing problems for less than a dozen of them. We have already submitted PRs with changes that will make them work the same way under both the current and proposed rules.
104+
For the detailed motivation of changes with examples of code that will be easier to write and understand, see our recent blogpost //// TODO LINK
110105

111106
Our current plan is to introduce the new scheme in Scala 3.7. Starting from Scala 3.6, code whose behavior can differ between new and old rules (ambiguity on new, passing on old, or vice versa) will emit warnings, but the old rules will still be applied. 3.5 gives you a chance to detect if those changes affect your codebase. Running the compiler with `-source 3.6` will give you warnings; with `-source 3.7` or `-source future` you will get the new scheme.
112107

@@ -116,4 +111,49 @@ There is already 3.5.1-RC1 published on Maven Central. This release contains mul
116111

117112
## Contributors
118113

119-
// TODO
114+
Thank you to all the contributors who made this release possible 🎉
115+
116+
According to `git shortlog -sn --no-merges 3.4.2..3.5.0` these are:
117+
118+
```
119+
153 Martin Odersky
120+
53 Eugene Flesselle
121+
41 Jamie Thompson
122+
29 Wojciech Mazur
123+
25 Nicolas Stucki
124+
22 Sébastien Doeraene
125+
18 noti0na1
126+
16 Matt Bovel
127+
13 Guillaume Martres
128+
11 Paweł Marks
129+
10 Hamza REMMAL
130+
9 Yichen Xu
131+
8 Jan Chyb
132+
7 Hamza Remmal
133+
7 Som Snytt
134+
6 Jędrzej Rochala
135+
5 Fengyun Liu
136+
5 dependabot[bot]
137+
3 Mikołaj Fornal
138+
2 Aviv Keller
139+
2 EnzeXing
140+
1 Chris Pado
141+
1 Filip Zybała
142+
1 Georgi Krastev
143+
1 Jisoo Park
144+
1 Katarzyna Marek
145+
1 Lucas Nouguier
146+
1 Lucy Martin
147+
1 Ola Flisbäck
148+
1 Pascal Weisenburger
149+
1 Quentin Bernet
150+
1 Raphael Jolly
151+
1 Seth Tisue
152+
1 Stephane Bersier
153+
1 Tomasz Godzik
154+
1 Yoonjae Jeon
155+
1 aherlihy
156+
1 rochala
157+
1 willerf
158+
159+
```

0 commit comments

Comments
 (0)