You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: blog/_posts/2024-10-15-scala-3.5.0-released.md
+62-22Lines changed: 62 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -76,37 +76,32 @@ assert(0B_1000_0010 == 130)
76
76
assert(0B_1000_0010 ==0x82)
77
77
```
78
78
79
-
##Work on a better scheme for given prioritization
79
+
### Experimental: named tuples
80
80
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.
82
82
83
83
```scala
84
-
traitFunctor[F[_]]:
85
-
extension [A, B](x: F[A]) defmap(f: A=>B):F[B]
86
-
traitMonad[F[_]] extendsFunctor[F] { ... }
87
-
traitTraverse[F[_]] extendsFunctor[F] { ... }
88
-
```
89
-
90
-
and corresponding instances
84
+
importscala.language.experimental.namedTuples
91
85
92
-
```scala
93
-
givenFunctor[List] =???
94
-
givenMonad[List] =???
95
-
givenTraverse[List] =???
96
-
```
86
+
typePoint= (x: Int, y: Int)
87
+
valpoint:Point= (x =1, y =2)
88
+
valis_it_point= (x =5, y =3)
89
+
valit_is:Point= is_it_point
97
90
98
-
Now, let's use the instances in the following context:
91
+
println(point.x) // prints 1
99
92
100
-
```scala
101
-
deffmap[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")
103
96
```
104
97
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).
106
99
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.
108
103
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
110
105
111
106
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.
112
107
@@ -116,4 +111,49 @@ There is already 3.5.1-RC1 published on Maven Central. This release contains mul
116
111
117
112
## Contributors
118
113
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:
0 commit comments