
ES6 in Depth: Symbols (2015) - fanf2
https://hacks.mozilla.org/2015/06/es6-in-depth-symbols/
======
SCdF
> ES6 symbols are similar to the more traditional symbols in languages like
> Lisp and Ruby, __but not so closely integrated into the language __.

This is why I'm not massively interested in ES6 symbols tbh, though I could be
missing something.

Hopefully there will still be useful cases for them.

~~~
ajanuary
It's also not really true: they're the opposite of symbols in lisp and ruby.
In lisp and ruby, `:a == :a` is true, while in JavaScript `Symbol("a") ==
Symbol("a")` is false.

~~~
TeMPOraL
They are similar, but with kind of inverted defaults.

Symbol("a") == Symbol("a") is more-less equivalent to Common Lisp's (eq (make-
symbol "a") (make-symbol "a")), both of which will return false, because (in
Lisp terms) we're _creating_ two different symbols. In Common Lisp, the
default behaviour of a reader if it sees a stand-alone symbol token, is to
_intern_ it - put it in "global"[0] storage, so that if the reader sees the
same-looking symbol token again, it returns _the same_ symbol instance it
previously interned.

In JavaScript, per this article, the interning behaviour is available through
Symbol.for(), i.e. Symbol.for("a") == Symbol.for("a") should return true, much
like (eq 'a 'a) would return true in Lisp.

\--

[0] - it's actually per-package storage, but that's getting into the more
advanced details of CL.

\--

EDIT replaced gensym with make-symbol in Common Lisp example, as the former is
used primarily in writing macros, so it ensures the created symbol has an
unique _printed representation_ , which helps make macroexpansions more
readable.

    
    
      (make-symbol "FOO") -> #:FOO
      (make-symbol "FOO") -> #:FOO ; NOT eq to the previous one
      (gensym "FOO") -> #:FOO103
      (gensym "FOO") -> #:FOO104 ; note the incrementing counter appended by gensym
    

Compare
[http://clhs.lisp.se/Body/f_mk_sym.htm](http://clhs.lisp.se/Body/f_mk_sym.htm)
and
[http://clhs.lisp.se/Body/f_gensym.htm](http://clhs.lisp.se/Body/f_gensym.htm).

~~~
Touche
But in Ruby people use symbols to specify an object's properties, and they
aren't used that way in JavaScript at all. In JavaScript they are used for
metadata and other things you don't want to be serialized by JSON.stringify()
or Object.assign(). I've always been confused by why Ruby uses symbols so
much.

~~~
masklinn
> In JavaScript they are used for metadata and other things you don't want to
> be serialized by JSON.stringify() or Object.assign().

They're used to _avoid conflicts_ for "generic method" hooks (similar to
dunder methods in Python): the conflict issues is why environments have broken
when new methods were added, and why e.g. Object.keys and their ilk are
"static" functions rather than methods.

If you don't want JSON.stringify or Object.assign to see your properties just
make them non-enumerable e.g.:

    
    
        > const obj = {};
        > Object.defineProperty(obj, 'prop', {'value': 42});
        > obj
        < {prop: 42}
        > JSON.stringify(obj)
        < "{}"
        > Object.assign({}, obj)
        < {}
    

Object.assign will copy symbol-keyed properties. In fact Symbol-keyed
properties are enumerable by default.

They live in an odd half-way world because many constructs only accept/handle
string-keyed properties: Object.keys/entries/values and JSON.stringify use
EnumerableOwnProperties and (for..in) uses EnumerateObjectProperties, both of
which are specified to ignore non-string-keyed properties (before even
checking for enumerability).

> I've always been confused by why Ruby uses symbols so much.

Mutable non-interned strings.

------
TomSawyer
Is this someone's slide deck as article? Beginning with what symbols aren't —
not logos, not emoji, not cymbals, har har — seems more suited for a cheesy
in-person ice breaker.

~~~
baq
it's also great for people who never heard of symbols and might have a
mistaken idea about what they might be.

------
skybrian
(2015)

In particular, hasInstance is apparently implemented by some browsers now:

[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance)

------
maxxxxx
I remember NewtonScript had symbols too. If I remember correctly they worked
quite similar but it's been a long time so I am not 100% sure.

