Skip to content

Commit 6b19a35

Browse files
Kordyjanprolativ
andauthored
Add 3.3.0 announcement (#1505)
Co-authored-by: Michał Pałka <[email protected]>
1 parent c45504c commit 6b19a35

File tree

4 files changed

+200
-3
lines changed

4 files changed

+200
-3
lines changed

_data/scala-releases.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
- category: current_version
2-
title: Current 3.2.x release
3-
version: 3.2.2
4-
release_date: January 30, 2023
2+
title: Current 3.3.x LTS release
3+
version: 3.3.0
4+
release_date: May 30, 2023
55
- category: current_version
66
title: Current 2.13.x release
77
version: 2.13.10

_downloads/2023-05-30-3.3.0.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Scala 3.3.0 LTS
3+
start: 30 May 2023
4+
layout: downloadpage
5+
release_version: 3.3.0
6+
release_date: "May 30, 2023"
7+
permalink: /download/3.3.0.html
8+
license: <a href="https://www.scala-lang.org/license/">Apache License, Version 2.0</a>
9+
api_docs: https://www.scala-lang.org/api/3.3.0/
10+
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
---
2+
layout: blog-detail
3+
post-type: blog
4+
by: Paweł Marks, VirtusLab
5+
title: Scala 3.3.0 released!
6+
---
7+
8+
![Scala 3.3]({{ site.baseurl }}/resources/img/scala-3.3_LTS-launch.png)
9+
10+
We are thrilled to announce that after long months of work and careful testing, we have released Scala 3.3.0, the first release in the new 3.3.x LTS series.
11+
12+
## What does "LTS" mean?
13+
14+
Scala 3.3.x is the first Long Term Support (LTS) release series. That means that it will be actively maintained for a period of at least three years. We have adopted a release model similar to the one that Java has successfully used for a long time.
15+
16+
In the following years, there will be new minor releases (3.4, 3.5, and so on) that can bring new backward-compatible features. We are calling them Scala Next; they are equivalent to Java's feature releases. Bug fixes and usability improvements from those releases will be back-ported and released as 3.3.x patches. Apart from those forward and backward-compatible changes, LTS will be feature frozen.
17+
18+
The LTS model doesn't change anything in our compatibility guarantees. Projects built with all future releases will be able to depend on any library compiled with Scala 3.3.x. This is just our standard guarantee that the newer compiler can always consume the output of the older version.
19+
20+
LTS might be a great choice for library authors who can now receive constant bug fixes and developer experience improvements without forcing the users of the library to update the compiler version in their project.
21+
22+
You can read more about our compatibility guarantees in [the recent blog post](https://virtuslab.com/blog/the-scala-3-compatibility-story/).
23+
24+
## What's new in Scala 3.3.0
25+
26+
### Linting
27+
28+
Scala 3.3.0 brings back linting to the Scala compiler. Right now, you can enable checking for unused symbols and discarded values. More linting options will come soon in the following Scala 3.3.x releases.
29+
30+
#### Checking for unused values
31+
32+
There is an entire family of compiler options added in 3.3.0 for checking and reporting different kinds of unused symbols:
33+
34+
- `-Wunused:imports` - for unused imports
35+
- `-Wunused:privates` - for unused local definitions
36+
- `-Wunused:locals` - for unused local definitions
37+
- `-Wunused:explicits` - for unused explicit parameters
38+
- `-Wunused:implicits` - for unused implicit parameters (parameters in `using` clauses)
39+
- `-Wunused:params` - for all unused method parameters
40+
- `-Wunused:all` - for enabling all of the above lints
41+
42+
#### Checking for discarded values
43+
44+
Discarding non-unit values is usually the symptom of subtle mistakes. The compiler can now warn you about all discarded values saving you from bugs resulting from those hard-to-spot mistakes.
45+
46+
In the following simplified example
47+
48+
```Scala
49+
def failure: Either[String, Nothing] = Left("something broke")
50+
51+
def failedComputation: Either[String, Unit] =
52+
Right(()).map(_ => failure)
53+
```
54+
55+
the programmer, by mistake, used the `map` method instead of `flatMap`. The code still compiles, but due to value discarding, behaves unexpectedly, returning `Right(())` from the `failedComputation` method. If the `-Wvalue-discard` flag is enabled, the compiler will report the warning, saving the user from a potential bug.
56+
57+
### More consistent braceless syntax
58+
59+
Braces around method parameters can now be replaced with a colon. This can lead to cleaner, shorter, and often more readable code in places like configuration DSLs or test case definitions.
60+
61+
```Scala
62+
def canFail(input: String): Try[List[String]] = Try:
63+
someComputation(input).flatMap: res =>
64+
val partial = moreComputation(res)
65+
andEvenMore(partial)
66+
67+
class TestSuite extends munit.FunSuite:
68+
test("the job doesn't fail"):
69+
val job = canFail("some data")
70+
assert(job.isSuccess)
71+
```
72+
73+
For the record, the braceless syntax has been introduced in Scala 3.0.0. However, braces were still needed to pass function arguments. Martin Odersky proposed to address this point in the proposal [SIP-44 - Fewer braces](https://docs.scala-lang.org/sips/fewer-braces.html), which was accepted by the SIP Committee in [August 2022](https://docs.scala-lang.org/sips/results/2022-08-26-meeting.html). The final implementation was released as an experimental feature in [Scala 3.2.0](https://github.com/lampepfl/dotty/releases/tag/3.2.0) in September. Finally, in [October](https://docs.scala-lang.org/sips/results/2022-10-21-meeting.html), the SIP Committee voted to promote it to a stable feature.
74+
75+
### `boundary` and `break`
76+
77+
Two new methods were added to the standard library: `boundary` and `break`. They are safer and more expressive replacements for non-local returns, which were deprecated recently.
78+
79+
`break` allows for a type-safe early escape from anywhere inside the block delimited by `boundary` to its end, returning the passed value from the entire block.
80+
81+
```Scala
82+
import util.boundary, boundary.break
83+
84+
def sumOfRoots(number: List[Double]): Option[Double] = boundary:
85+
val roots = numbers.map: n =>
86+
println(s" * calculating square root for $n*")
87+
if n >= 0 then Math.sqrt(n) else break(None)
88+
Some(roots.sum)
89+
```
90+
91+
When you run the above method, you will notice that it returns `None` when any of the input elements is negative. Moreover, thanks to `boundary`/`break`, you can see from the console output that it stops iterating after encountering the first negative element.
92+
93+
`break` can jump out of the `boundary` in the function deeper on the stack. To make it safe, only functions with a matching `Label` in their using clauses can break. This can be used to create isolated parts of an application with streamlined error handling. Library authors can abstract over `break` and `Label`, creating a nice API for error handling or dealing with uncertain data.
94+
95+
### The new default implementation of lazy vals
96+
97+
Last but not least, we have changed the default implementation of lazy vals. The new implementation has better performance and is safer under parallel access. This may result in improvements in the performance of effect systems.
98+
99+
## Should I update to Scala 3.3.0?
100+
101+
If you are maintaining a standalone Scala 3 project without external projects depending on it, feel free to switch to Scala 3.3.0 at any moment. You will enjoy all the improvements in the newest version of the compiler.
102+
103+
If you are a library author following semantic versioning, we advise you to update to Scala 3.3.0 in the next minor release of your project. Users of your library would also need to bump their compiler version to use the newest version of your library. If you have already published a minor version on 3.3.0 but learned about a critical vulnerability in your library, you should release a new patch release for the previous minor version of your library using the Scala version you had used before the bump (e.g. 3.2.2 or older). This patch can be consumed by all the users of previous versions of the library, no matter if they have already switched to 3.3.0 or not.
104+
105+
### Known incompatibility: Stability of inline parameters
106+
107+
In Scala, only stable paths can be used as prefix in path-dependent types.
108+
109+
```Scala
110+
class Outer:
111+
type Inner
112+
113+
val a = new Outer
114+
val aInner: a.Inner = ??? // ok
115+
116+
var b = new Outer
117+
// val bInner: b.Inner = ??? // error
118+
119+
def c = new Outer
120+
// val cInner: c.Inner = ??? // error
121+
122+
def method(param: Outer): param.Inner = ??? // ok
123+
```
124+
125+
There was a bug that resulted in the compiler assuming that all inline parameters are stable references. This could have led to unsound code being accepted by the compiler and potential runtime crashes.
126+
127+
```Scala
128+
inline def method(inline param: Outer): param.Inner // error in Scala 3.3.0
129+
```
130+
131+
Such pieces of code are now rejected by the compiler. The migration for that change is simple, as it only requires removing the `inline` modifier **from the parameter**. If the path-dependent type was used, it is safe to say that the intended behavior was to inline the method without inlining the parameter.
132+
133+
## Contributors
134+
135+
Thank you to all the contributors who made the release of 3.3.0 possible
136+
137+
According to `git shortlog -sn --no-merges 3.2.2..3.3.0` these are:
138+
139+
```
140+
226 Martin Odersky
141+
106 Szymon Rodziewicz
142+
81 Dale Wijnand
143+
56 Nicolas Stucki
144+
52 Paul Coral
145+
48 Kamil Szewczyk
146+
45 Paweł Marks
147+
28 Florian3k
148+
28 Yichen Xu
149+
15 Guillaume Martres
150+
10 Michał Pałka
151+
9 Kacper Korban
152+
8 Fengyun Liu
153+
7 Chris Birchall
154+
7 rochala
155+
6 Sébastien Doeraene
156+
6 jdudrak
157+
5 Seth Tisue
158+
5 Som Snytt
159+
5 nizhikov
160+
4 Filip Zybała
161+
4 Jan Chyb
162+
4 Michael Pollmeier
163+
4 Natsu Kagami
164+
3 Anatolii Kmetiuk
165+
3 Jamie Thompson
166+
2 Adrien Piquerez
167+
2 Alex
168+
2 Dmitrii Naumenko
169+
2 Lukas Rytz
170+
2 Michael Pilquist
171+
2 Vasil Vasilev
172+
2 adampauls
173+
2 yoshinorin
174+
1 Alexander Slesarenko
175+
1 Chris Kipp
176+
1 Guillaume Raffin
177+
1 Jakub Kozłowski
178+
1 Jan-Pieter van den Heuvel
179+
1 Julien Richard-Foy
180+
1 Kenji Yoshida
181+
1 Matt Bovel
182+
1 Mohammad Yousuf Minhaj Zia
183+
1 Philippus
184+
1 Szymon R
185+
1 Tim Spence
186+
1 s.bazarsadaev
187+
```
342 KB
Loading

0 commit comments

Comments
 (0)