gleam-lang/gleam

Use singleton values for fieldless variants and the empty list on JavaScript

Open

#5,756 创建于 2026年5月26日

在 GitHub 查看
 (1 评论) (0 反应) (0 负责人)Rust (21,417 star) (960 fork)batch import
help wanted

描述

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).

贡献者指南