Compiler ยท Jul 17, 2018

Announcing BuckleScript 4.0 (Part Two)

Hongbo Zhang
Compiler Team

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.

Want to read more?
Back to Overview