Skip to content
This repository was archived by the owner on Apr 3, 2025. It is now read-only.
This repository was archived by the owner on Apr 3, 2025. It is now read-only.

Potential alternative: Special lexical declarations for literal syntax #26

@littledan

Description

@littledan

What if we used syntax like this for extended numeric literals?

import { BigDecimal, bigDecimalLiteral } from "./bigdecimal.mjs";
with literal 0d from bigDecimalLiteral;

.1d + .2d === .3d;

Based on the implementation:

// bigdecimal.mjs
class BigDecimal { /* ... */ }

let literalCache = new WeakMap();
export function bigDecimalLiteral(obj) {
  // obj is of the form Object.freeze({string: "123", number: 123})
  if (literalCache.has(obj)) { return literalCache.get(obj); }
  let decimal = new BigDecimal(obj.string);
  literalCache.set(obj, decimal);
  return decimal;
}

Many people (most recently, @erights) have independently given the feedback that it is pretty unfortunate to have to use an extra symbol, whether it's 3@d or 3_d or 3'd, for extended numeric literals. Wouldn't it be great if we could just use 3d, as shown above?

This would be basically like the pre-decorators semantics, but with the twist that, rather than requiring the names start with _, we'd put literal suffixes in a separate namespace! What do you think?

Using a separate namespace might allow us to shadow built-in suffixes (0n) while preserving static analyzability: it's important to be able to understand that 123n is a BigInt statically, if the n suffix is not being shadowed. Some lexical scopes are quite dynamic (e.g., the global object), so if 0n involved an ordinary lexical lookup, and fallback back to the built-in one, it wouldn't be very statically analyzable. By contrast, if we put these in a separate namespace, which is only manipulated by more predictable statements, this regularity would be preserved.

I've heard that, in ES4 times, there was a "no namespaces" resolution. I don't really know what that implies (cc @waldemarhorwat @BrendanEich); apparently private names were acceptable with respect to this goal.

The idea here would be that the with keyword would, in general, mean, "something is being added to the lexical scope". This unifies the with operators from statement proposed in the operator overloading proposal as well as the legacy, deprecated with () { } statement to add an object to lexical scope. Before the with literal statement is executed, that literal would be "in TDZ" if used.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions