-
Notifications
You must be signed in to change notification settings - Fork 329
Add 3.5.0 announcement #1676
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
Add 3.5.0 announcement #1676
Changes from 1 commit
6c6d932
7f0fd24
7e5f614
c1c7170
d85a47f
59282e6
9238565
e260cf5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
--- | ||
layout: blog-detail | ||
post-type: blog | ||
by: Paweł Marks, VirtusLab | ||
title: Scala 3.5.0 released! | ||
--- | ||
|
||
 | ||
|
||
We are happy to announce that after the long and hard work of the entire compiler team and seven release candidates, the first version of the Scala 3.5 line is officially out! | ||
|
||
## New default runner - Scala CLI | ||
|
||
[Scala CLI](https://scala-cli.virtuslab.org/) is a popular tool among Scala devs. It allows lightning-fast running, testing, and prototyping of small Scala projects and scripts. Since 3.5.0, it has become a part of the default Scala distribution. If you install Scala through popular package managers, such as Brew or SDKMAN!, the installed `scala` command will allow you to compile, run, test, and even publish your code on Maven Central. It will have out-of-the-box support using-directives, toolkits, compilation to native and js targets, and other goodies formerly available only if you installed a third-party tool. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Short example | ||
|
||
If we have the following file named `biggerThan.scala` | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```scala | ||
//> using dep com.lihaoyi::os-lib:0.10.3 | ||
|
||
@main def run(path: String, size: Int) = | ||
os.list(os.Path(path, os.pwd)) | ||
.filter: p => | ||
os.size(p) > size * 1024 | ||
.foreach(println) | ||
``` | ||
|
||
We can run `scala biggerThan -- ../my-directory 10`. This will download the os-lib and all its transitive dependencies, then compile the source file, and finally run the compiled program, printing all files in `../my-directory` bigger than 10 kB. Subsequent invocations of the command will use cached binary, or in case of changes in the file, trigger incremental compilation. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
As os-lib is a part of the default Scala toolkit, we can replace the `//> using dep com.lihaoyi::os-lib:0.10.3` line with `//> using toolkit default`. Furthermore, we can add `#!/usr/bin/env -S scala shebang` at the top of the file. Then, after setting the permissions, we can treat `biggerThan.scala` as any executable script. Invoking `./biggerThan.scala ../my-directory 10` will incrementally compile the file and then run it. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To learn the full scope of the new capabilities, read about Scala CLI [commands](https://scala-cli.virtuslab.org/docs/commands/basics/) and [using-directives](https://scala-cli.virtuslab.org/docs/reference/directives) or glance at [the cookbook](https://scala-cli.virtuslab.org/docs/cookbooks/intro). | ||
|
||
Merging Scala CLI into the compiler doesn't change the behavior of popular build tools, such as sbt or Mill. It will, however, allow for maintaining and publishing single-module multiplatform libraries without any build tool. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## What's new in 3.5.0? | ||
|
||
### Best Effort Compilation | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
When using Metals, the IDE functions work great as long as the code passes the compilation. However, once the user starts changing the code, the support drops in quality. This gets worse with a larger number of compilation errors and subsequent modifications. In 3.5.0, we have fixed this problem. We introduced a new mode of compilation called Best Effort Compilation. When enabled, the compiler will output BETASTy files for not compiling code. It can be used by tooling to provide autocompletion and other IDE features. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To enable the use of BETASTy files in Metals, start the language server with `-Dmetals.enable-best-effort=true` or put that into `metals.serverProperties` setting in VS Code. | ||
|
||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
### Support for Pipelined Builds | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Scala 3.5.0 supports pipelined compilation. It can be enabled by setting `ThisBuild/usePipelining := true` in sbt build definition. This can result in significant speedups in compilation time for multi-module projects. | ||
|
||
You can learn more about how the pipelined compilation works and what benefits you can expect from [the talk by Jamie Thompson](https://www.youtube.com/watch?v=1uuFxEAiPuQ&t=1473s). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there also something in textual form people can look at...? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there are only various PR comments and commit messages -and forum post on Scala Contributors - Someone™️ should bring together this information |
||
|
||
### `var` in refinements | ||
|
||
Until now, only types, `val`s, and `def`s were allowed in type refinements. In 3.5.0, `var`s can also be declared. | ||
|
||
```scala | ||
type A = { var number: Int } | ||
``` | ||
|
||
is now legal and equivalent to | ||
|
||
```scala | ||
type A = { def number: Int, def number_=($number: Int): Unit } | ||
``` | ||
|
||
This change can simplify libraries based on metaprogramming using type refinements. | ||
|
||
### Support for binary integer literals | ||
|
||
Integer literals can now start with `0b` or `0B`. They will be interpreted as numbers in base 2. | ||
|
||
```scala | ||
assert(0B1 == 1) | ||
assert(0B10 == 2) | ||
assert(0B_1000_0010 == 130) | ||
assert(0B_1000_0010 == 0x82) | ||
``` | ||
|
||
## Work on a better scheme for given prioritization | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section may seem longer than necessary, but we really want people to test the new given prioritization scheme. |
||
|
||
Givens in Scala 3 have a peculiar problem with prioritization. To illustrate it, let's consider the following inheritance triangle for type classes: | ||
|
||
```scala | ||
trait Functor[F[_]]: | ||
extension [A, B](x: F[A]) def map(f: A => B): F[B] | ||
trait Monad[F[_]] extends Functor[F] { ... } | ||
trait Traverse[F[_]] extends Functor[F] { ... } | ||
``` | ||
|
||
and corresponding instances | ||
|
||
```scala | ||
given Functor[List] = ??? | ||
given Monad[List] = ??? | ||
given Traverse[List] = ??? | ||
``` | ||
|
||
Now, let's use the instances in the following context: | ||
|
||
```scala | ||
def fmap[F[_] : Functor, A, B](c: F[A])(f: A => B): F[B] = c.map(f) | ||
fmap(List(1,2,3))(_.toString) // ERROR | ||
``` | ||
|
||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: link to the blog post once it's available (#1675) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another possibility would be to greatly shorten this section and let the blog post do most of the work There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recently heard from @bracevac that the post will be closer to 3.6. This is why I needed to include the information about the planned changes right now. |
||
## What's next? | ||
|
||
There is already 3.5.1-RC1 published on Maven Central. This release contains multiple fixes and small improvements merged after we branched off the 3.5.0 to focus on polishing it. The release of the next version in the LTS line is coming soon. Scala 3.3.4-RC1 is available for testing. It contains all the forward and backward-compatible fixes up until Scala 3.5.0. | ||
Kordyjan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Contributors | ||
|
||
// TODO |
Uh oh!
There was an error while loading. Please reload this page.