New Changes
bs-platform
4.0.0 introduces a new runtime representation for optionals.
While beforehand None
was represented at runtime as 0
and Some("hello")
as an array ["hello"]
, the new representation tries to unbox optionals as
much as possible.
Now None
is represented as undefined
and Some("hello")
simply as
"hello"
.
Generally speaking, Some(v)
is represented as v
, i.e. unboxed. The only
exception is when v
itself is None
or Some(...(Some(None))
, in which case
a special boxed representation is used.
The construction of new values Some(-)
, and pattern matching | Some(-) =>
...
, perform some case analysis to decide when to box or unbox values. In the
absence of nested optionals, the result of both operations will always be the
indentity.
Because of that, it's possible to use type-based optimization to avoid
performing case analysis in the first place. So while the generic function
(x) => Some(x)
will generate code to check wheter x
should be boxed,
the more type-specific function (x:int) => Some(x)
is just compiled as
the identity function, as it's clear from the type that no boxing is required.
For a high-level formalization of the boxing and unboxing operations, as well as the polymorphic comparison functions, see this gist.
One design choice was whether to represent None
as null
or as undefined
.
The choice of undefined
was made because this allows a direct mapping for
optional labeled
arguments.
As a consequence null
is never boxed, so e.g. Some(null)
is represented as
null
.