Skip to content

Instantly share code, notes, and snippets.

@arv
Last active December 20, 2015 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arv/0bbb184710016e00d56c to your computer and use it in GitHub Desktop.
Save arv/0bbb184710016e00d56c to your computer and use it in GitHub Desktop.

Unique Public Symbols as Strings

Instead of introducing unique public symbols we propose to use a normal string property that is a UUID. This is referred to as unique string throughout this text. Unique strings contains non identifier characters to encourage usage of them using the constant defining them instead of MemberExpression or IdentifierName in Object literals.

Pros:

  1. No new semantics.
  2. No need for new mechanism to share objects across different realms.

Cons:

  1. Enumerable by default

Usage

We introduce a new function that creates unique strings. It can take an optional name that is prepended to the string. This is to make it easier to associate the string with something human readable.

  var key1 = String.unique();
  // "5579e3cd-1820-42d2-b109-389ae21914e1"
  var key2 = String.unique('data');
  // "data-ad9def47-ace6-4856-95a0-f0adebb212c4"

  var object = {
    [key1]: 1,
    [key2]: 2
  };

Symmetries with Unique Symbols

Discoverabilty

Both unique symbols and unique strings are discoverable.

var sym = Symbol();
var uniqueString = String.unique();
var obj = {};
obj[sym] = 1;
obj[uniqueString] = 2;
Object.getOwnPropertyKeys(obj)[1] === sym;
Object.getOwnPropertyNames(obj)[1] === uniqueString;

Proxies

Properties that are defined using unique symbols already invoke th eproxy traps.

Object.observe

Properties that are defined using unique symbols already trigger notification of the notifier

var sym = Symbol();
var object = {};
var object[sym] = 1;
Object.observe(object, records => {
  assert(records[0].name === sym);
});
object[sym]++;

Well-Known Symbols and Intrinsics

Changing these to unique symbols does not affect the APIs in any way. It is recommended that these are non enumerable by default to not show up in for-in loops.

import {
  create,
  iterator,
  toStringTag
} from '@std';

class Set {
  ...
  static [create]() { ... }
  [iterator]() { ... }
  [toStringTag]() { ... }
}
Object.defineProperty(Set, create, {enumerable: false});
Object.defineProperty(Set.prototype, iterator, {enumerable: false});
Object.defineProperty(Set.prototype, toStringTag, {enumerable: false});

Even though we could generate new UUID every time the VM starts up, we are proposing to specify the well-known unique strings in the spec. This is so that they survive the lifetime of the current execution and can be shared between different instances of the VM on the same, or on a different computer.

The well-known symbols (at this point) are:

@@create "create-06e5207d-28e7-473e-a16e-89ea2f873be7"
@@hasInstance "hasInstance-69c8bbc6-70d0-4edb-972a-8a7f60199491"
@@isRegExp "isRegExp-12d0b914-5c59-4085-858a-6e3bad414089"
@@iterator "iterator-2ea7499f-4688-462e-978d-82b1fb67cb7d"
@@ToPrimitive "ToPrimitive-5d9632f5-6534-46ec-950b-db70396db320"
@@toStringTag "toStringTag-7c4c7683-49c9-4e31-a165-f94e4841fc4f"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment