tc39 / proposal-extended-numeric-literals

Extensible numeric literals for JavaScript
https://tc39.github.io/proposal-extended-numeric-literals/
72 stars 18 forks source link

Overlap with tagged template literals / Number prototype properties #16

Open queerviolet opened 6 years ago

queerviolet commented 6 years ago

We already have template literals and an extensible Number.prototype. The value prop here seems a bit low for a syntactic change.

This works today:

const unit = name => {
  const f = (pieces, ...cooked) => ({
    [f]:
      Array.isArray(pieces)
        ? String.raw(pieces, ...cooked)
        : String(pieces),
  })

  const sym = Symbol(name)
  f[Symbol.toPrimitive] = () => sym
  Object.defineProperty(Number.prototype, f, {get() { return f(this) }})
  Object.defineProperty(String.prototype, f, {get() { return f(this) }})
  return f
}

const m = unit('meters')

10[m]    // {Symbol(meters): "10"}
m`42`    // {Symbol(meters): "42"}
'99'[m]  // {Symbol(meters): "99"}

// And of course it works on variables
const len = 20
len[m]   // {Symbol(meters): "20"}

// Expressions
(2 + 3)[m]  // {Symbol(meters): "5"}

// And it's a function, so we can do function things with it.
[20, 40, 50].map(m)
  // [ {Symbol(meters): "20"}, {Symbol(meters): "40"}, {Symbol(meters): "50"} ]

Yes, extending global prototypes is not ideal, but doing it with Symbols is very safe—I can't see any problems with the above. Even if we have multiple versions of the same library trying to walk all over each other, they won't be able to.

Are there use cases I'm missing?

littledan commented 6 years ago

These are both interesting ideas, and we might want to make the tradeoff of encouraging those idioms rather than introducing a new language feature. Here are some considerations that led to this proposal: