Semantics of Scala.js and how they differ from Scala
Because the target platform of Scala.js is quite different from that of Scala, a few language semantics differences exist.
Numbers and characters
Long, all primitive number types of Scala.js, as well as the
Double's, and no overflow
detection is performed.
This means that operations on numbers that would overflow their range do not wrap, but instead take on bigger values.
Integer division does follow the expected semantics, though, i.e., it always return an integer.
Binary operations (
|, etc.) are always performed on signed 32-bit
Longs are 64-bits and follow the same semantics as on the JVM.
Note that float literals are still truncated to their (binary) precision. However, output does not truncate to that precision. This can lead to the following behavior (this works as expected when using doubles):
println(13.345f) // Scala: 13.345 // Scala.js: 13.345000267028809
conversion to or from other character sets. As a result,
Byte arrays are not supported by Scala.js.
Java reflection and, a fortiori, Scala reflection, are not supported. There is
limited support for
obj.getClass.getName will work
In general, Scala.js supports exceptions, including catching them based on their type. However, exceptions that are typically triggered by the JVM have flaky semantics, in particular:
ArrayIndexOutOfBoundsExceptionis never thrown.
This sometimes has an impact on functions in the Scala library that use regular expressions themselves. A list of known functions that are affected is given here:
StringLike.split(x: Array[Char])(see issue #105)
scala.Symbol is supported, but is a potential source of memory leaks
in applications that make heavy use of symbols. The main reason is that
by Scala.js tow remain in memory throughout the lifetime of the application.
Value(i: Int) on
reflection to retrieve a string representation of the member name and
are therefore -- in principle -- unsupported. However, since
Enumerations are an integral part of the Scala library, Scala.js adds
limited support for these two methods:
- Calls to either of these two methods of the forms:
are statically rewritten to
val <ident> = Value val <ident> = Value(<num>)Note that this also includes calls like
val <ident> = Value("<ident>") val <ident> = Value(<num>,"<ident>")since they are desugared into separate
val A,B,C,D = Value
- Calls to either of these two methods which could not be rewritten will issue a warning.
We believe that this covers most use cases of
scala.Enumeration. Please let us know if another (generalized)
rewrite would make your life easier.