-
Notifications
You must be signed in to change notification settings - Fork 12
Potential alternative: Special lexical declarations for literal syntax #26
Description
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?