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
We are excited to announce the release of Scala.js 1.9.0!
11
+
12
+
Starting with this release, Scala.js will use its strict-floats mode by default (what previously required `withStrictFloats(true)`).
13
+
`Float` values are now always guaranteed to fit in 32-bit floating point data, and all `Float` operations strictly follow IEEE-754 float32 semantics.
14
+
15
+
This release also brings support for `java.util.BitSet`, and fixes some bugs.
16
+
It also updates the version of the Scala standard library to 2.13.8 for 2.13.x versions.
17
+
18
+
Read on for more details.
19
+
20
+
<!--more-->
21
+
22
+
## Getting started
23
+
24
+
If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/).
25
+
26
+
If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js).
27
+
28
+
Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues).
29
+
30
+
## Release notes
31
+
32
+
If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes.
33
+
34
+
This is a **minor** release:
35
+
36
+
* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.8.x can be used with 1.9.0 without change.
37
+
* Despite being a minor release, 1.9.0 is forward binary compatible with 1.8.x. It is *not* forward binary compatible with 1.7.x. Libraries compiled with 1.9.0 can be used with 1.8.x but not with 1.7.x or earlier.
38
+
* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.8.x (in particular in the presence of `-Xfatal-warnings`).
39
+
40
+
As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first.
41
+
42
+
## Strict floats by default
43
+
44
+
### Background
45
+
46
+
Until 1.8.0, Scala.js used non-strict floats by default.
47
+
This meant that `Float` values and their operations were allowed to behave like `Double`s; either always, sometimes or never, in unpredictable ways.
48
+
This was done in the name of run-time performance, because correctly implementing 32-bit float operations requires the built-in function [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround).
49
+
It was considered acceptable because there are few use cases for demanding the reduced precision of `Float`s, and even the JDK did not mandate strict floating point operations by default.
50
+
51
+
It was always possible to require the Scala.js linker to use strict float semantics using the following setting:
Starting with 1.9.0, Scala.js uses strict float semantics by default.
60
+
The rationale for this change is that several conditions have changed since Scala.js was first designed:
61
+
62
+
* We emit ECMAScript 2015 by default, which requires that `Math.fround` be available
63
+
* Even when targeting ES 5.1, `Math.fround` has been widely available in browsers and other JS engines for years
64
+
*[Java 17 restored strict floating point operations everywhere](https://openjdk.java.net/jeps/306)
65
+
66
+
Using strict floats means that `Float` values will always be representable with 32 bits, and that `Float` operations will always follow the IEEE-754 specification for the `float32` format.
67
+
This should not have any impact except in the following case:
68
+
69
+
*`x.isInstanceOf[Float]` used to return `true` when `x` was any `number`. It will now return `false` if it cannot be represented with a 32-bit float.
70
+
71
+
This change of semantics can in theory break some code, although we do not expect that to happen on any non-contrived example.
72
+
73
+
Since using strict float semantics is a link-time decision, it applies to the whole program.
74
+
Therefore, the changes are also applied to the code in libraries that you may use.
75
+
76
+
### Performance impact
77
+
78
+
The switch to strict floats may have a slight performance impact on the `isInstanceOf[Float]` operation, although benchmarks suggest that it is negligible.
79
+
80
+
There *will* be a performance impact if you are targeting a JS engine that does *not* support `Math.fround` (such as Internet Explorer), which implies emitting ES 5.1 code.
81
+
On such engines, Scala.js uses its own version of `fround` in user land (a so-called *polyfill*).
82
+
We have optimized our `fround` polyfill to the greatest extent possible, but benchmarks still suggest that `Float`-intensive applications can experience up to a 4x performance hit.
83
+
84
+
### Reverting to non-strict float semantics
85
+
86
+
If you really want to, you can switch back to non-strict float semantics with the following linker setting:
Copy file name to clipboardExpand all lines: doc/semantics.md
+24-32
Original file line number
Diff line number
Diff line change
@@ -10,26 +10,7 @@ However, a few differences exist, which we mention here.
10
10
11
11
## Primitive data types
12
12
13
-
All nine primitive data types of Scala, i.e., `Boolean`, `Char`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double` and `Unit`, work exactly as on the JVM, with the following four exceptions.
14
-
15
-
### Floats can behave as Doubles by default
16
-
17
-
Scala.js underspecifies the behavior of `Float`s by default.
18
-
Any `Float` value can be stored as a `Double` instead, and any operation on
19
-
`Float`s can be computed with double precision.
20
-
The choice of whether or not to behave as such, when and where, is left to the
21
-
implementation.
22
-
23
-
If exact single precision operations are important to your application, you can
24
-
enable strict-floats semantics in Scala.js, with the following sbt setting:
All nine primitive data types of Scala, i.e., `Boolean`, `Char`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double` and `Unit`, work exactly as on the JVM, with the following three exceptions.
33
14
34
15
### `toString` of `Float`, `Double` and `Unit`
35
16
@@ -58,27 +39,19 @@ type they were created with. The following are examples:
- 1.4 matches `Double` only if strict-floats are enabled,
67
-
otherwise `Float` and `Double`
68
-
(unlike 1.5, the value 1.4 cannot be represented in a strict 32-bit `Float`)
46
+
- 1.4 only matches `Double`
47
+
(unlike 1.5, the value 1.4 cannot be represented in a 32-bit `Float`)
69
48
-`NaN`, `Infinity`, `-Infinity` and `-0.0` match `Float`, `Double`
70
49
71
50
As a consequence, the following apparent subtyping relationships hold:
72
51
73
52
Byte <:< Short <:< Int <:< Double
74
53
<:< Float <:<
75
54
76
-
if strict-floats are enabled, or
77
-
78
-
Byte <:< Short <:< Int <:< Float =:= Double
79
-
80
-
otherwise.
81
-
82
55
### `getClass()`
83
56
84
57
In Scala/JVM as well as Scala.js, when assigning a primitive value to an `Any` (or a generic type), and asking for its `getClass()`, Scala returns the *boxed class* of the value's type, rather than the primitive value.
@@ -94,6 +67,25 @@ Instead, it uses the more sensible `java.lang.Void`, as `Void` is the boxed clas
94
67
This means that while `java.lang.Void` is not instantiable on the JVM, in Scala.js it has a singleton instance, namely `()`.
95
68
This also manifests itself in `Array[Unit]` which is effectively `Array[java.lang.Void]` at run-time, instead of `Array[scala.runtime.BoxedUnit]`.
96
69
70
+
### Non-strict floats (deprecated; default until Scala.js 1.8.0)
71
+
72
+
Until v1.8.0, Scala.js underspecified the behavior of `Float`s by default with so-called *non-strict floats*.
73
+
74
+
Non-strict floats can still be enabled with the following sbt setting:
Under non-strict floats, any `Float` value can be stored as a `Double` instead, and any operation on `Float`s can be computed with double precision.
81
+
The choice of whether or not to behave as such, when and where, is left to the implementation.
82
+
In addition, `x.isInstanceOf[Float]` will return `true` for any `number` values (not only the ones that fit in a 32-bit float).
83
+
84
+
Non-strict floats are deprecated and will eventually be removed in a later major or minor version of Scala.js.
85
+
86
+
Enabling non-strict floats may significantly improve the performance (up to 4x for `Float`-intensive applications) when targeting JS engines that do not support [the `Math.fround` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround), such as Internet Explorer (which implies emitting ES 5.1 code).
87
+
If you are in that situation, we advise to use `Double`s instead of `Float`s as much as possible.
88
+
97
89
## Undefined behaviors
98
90
99
91
The JVM is a very well specified environment, which even specifies how some
0 commit comments