Use singleton values for fieldless variants and the empty list on JavaScript
#5,756 opened on 2026年5月26日
説明
The empty list and variants without fields are singletons, and all instances/uses of it are exactly the same. The Erlang implementation takes advantage of this so there is only ever one of each, but on the JavaScript implementation a new object is allocated for each use. This results in a small but pervasive performance cost.
Change the JavaScript implementation create a single instance of each of these values and to always use them.
Here is a proposed design. The exact design is open to discussion and can be changed.
Fieldless variant
pub type Wibble {
Wobble
}
pub const constant = Wobble
pub fn expression() -> Wibble {
Wobble
}
import { CustomType as $CustomType } from "./gleam.mjs";
export class Wobble extends $CustomType {}
export const Wibble$Wobble$const = new Wobble(); // <- New
export const Wibble$Wobble = () => Wibble$Wobble$const; // <- Changed
export const Wibble$isWobble = (value) => value instanceof Wobble;
export const constant = /* @__PURE__ */ Wibble$Wobble$const; // <- Changed
export function expression() {
return Wibble$Wobble$const; // <- Changed
}
Empty list
pub const constant = []
pub fn expression() -> List(a) {
[]
}
import { List$NonEmpty$const } from "../gleam.mjs";
export const constant = List$NonEmpty$const; // <- Changed
export function expression() {
return List$NonEmpty$const; // <- Changed
}
The same change to the external API would be made for the prelude for the empty list.
No differences are to be made to equality testing as existing code may be using the constructor directly. Once all code is using the correct API we can further optimise equality testing.
In a previous discussion it was suggested we could store the singleton instance as a static property on the class object, but I opted for a const as I believe this will minify better (as property names do not get mangled).