Why not using something more of the lines with Ruby's :symbol syntax?
You can't go around peppering your code with use of this new syntax if you want it to continue working on older runtimes. With `Symbol`, you can at least create a polyfill that approximates what it's shooting for.
> declaring a Symbol
Don't think of it as "declaring a symbol" (because it isn't). Think of it as generating a symbol (because it is).
Who really wants to write map.add(new Symbol("foo"), 'bar') instead of map.add(#foo, 'bar')?
It makes it clear when you are generating new symbol, and when you are reusing existing symbol.
var a = new Symbol("foo");
var b = new Symbol("foo");
map[a]="firstValue";
map[b]="secondValue";
Console.log(map[a] + " " + map[b]);
// writes "firstValue secondValue"
How does it work with your syntax? map[#foo]="firstValue";
map[#foo]="secondValue";
Console.log(map[#foo]); // what is written here?Nobody because it's completely daft, and absolutely not equivalent to the second version, the equivalent to the second version is:
map.add("foo", "bar")In particular object[:symbol] would behave quite differently (and would be probably worthless since everytime you would access a new property ).
It would make more sense to have :symbol a shortcut for Symbol.for("symbol") instead, but I don't think it would be that much useful.
Because Ruby's symbols are completely different and designed to collide. A Ruby symbol (like an Erlang atom) is a very cheap immutable string-like structure but :symbol is :symbol.
A Javascript symbol is (as others noted) much closer to a lisp unique symbol (the output of `gensym`), and having it be a function is perfectly fine since you have to keep it around anyway (or you can't access symbol-named properties).
Symbol.for is roughly equivalent to :symbol, but the use case for it is much more limited and there's really no reason for a literal version./
You mean Common Lisp's syntax, of course.
this is nothing but a more convoluted way of the pattern that sets a unique object as a unique value for comparison. well, it adds a label for easy debug. hooray.
(I do think symbols are useful though, replied for correctness.)
let x = Symbol.for("omghax");
let foo = Object.create(null)
foo[x] = 'bar';
Object.keys(foo).length // returns 0The most simple way to use them is to replace definitions like this one
var north = 1;
var south = 2;
var east = 3;
var west = 4;
var direction1 = north;
var direction2 = south;
direction1 === direction2 ? "ops" : "ok";
The programmer is doing the work of the interprer/compiler here and make sure to pick unique values for all the constants that are going to be compared together. With symbols that becomes var north = new Symbol();
var south = new Symbol();
var east = new Symbol();
var west = new Symbol();
var direction1 = north;
var direction2 = south;
direction1 === direction2 ? "ops" : "ok";
which is an improvement even if it is (in a traditional JavaScript way) so much more verbose than Ruby's direction1 = :north
direction2 = :south
direction1 === direction2 ? "ops" : "ok"
I just wish they'll add some syntactical sugar to do without that "new Symbol()" thing and create symbols as needed like Ruby does.Unfortunately, from https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...
Symbols and JSON.stringify()
Symbol-keyed properties will be completely ignored when using JSON.stringify():
JSON.stringify({[Symbol("foo")]: "foo"});
// '{}'
We're going to manually serialize them when they leave the RAM.The gist is this: symbols are just a way to have non-strings that you can use for properties. There are also facilities to generate them in such a way that the symbol will never, ever collide with those generated by somebody else, but that's not their only purpose.
s1 = Symbol.for('cat')
s2 = Symbol.for('cat')
s1 === s2 // true
The most common use-case for them is to generate symbols that don't collide, though.Looks like an anti-pattern to me.
If you want one particular symbol from some library, you could import it.
Have they added inbuilt support for globals here? People could easily add their own global symbols, why does this need to be built in?
Common Lisp has something even closer for its macro system. When you write code that writes code, you often need to create new variable names that won't collide or shadow anything. `(gensym)` does that: http://www.lispworks.com/documentation/lw50/CLHS/Body/f_gens....
Here's a list of languages with support for symbols. You will see even Objective-C has it: https://en.wikipedia.org/wiki/Symbol_%28programming%29#Suppo....
I'd be curious to learn how it is implemented in JS engines.
See http://blog.peschla.net/doxygen/v8_chromium_r157275/classv8_... - it's
None of the symbols in that table match the purpose and use case for `new Symbol`, though gensym does.
From A Rossberg (he's also the guy behind SoundScript) in a March 2014 stackoverflow post (http://stackoverflow.com/questions/21724326/why-bring-symbol...):
"Enabling private properties ... was indeed the original motivation for introducing symbols into JavaScript. Unfortunately, however, they ended up being severely downgraded, and not private after all.
They are now known as unique symbols, and their only use is to avoid name clashes between properties....Whether that is strong enough a motivation to add symbols to the language is debatable."
and from R. Waldron as part of this response (https://esdiscuss.org/topic/proposal-about-private-symbol) to a proposal about a private symbol (Dec 2014)
"Ultimately it was decided that Symbol is just a symbol and that "private" things will be dealt with orthogonally (and at a later date)."
YMMV
http://raganwald.com/2015/06/04/classes-are-expressions.html
HN discussion:
Lisp:
CL-USER 1 > (eq (make-symbol "Foo") (make-symbol "Foo"))
NIL
> Symbols aren’t exactly like anything else CL-USER 2 > (type-of (make-symbol "Foo"))
SYMBOL
> Trying to concatenate a symbol with strings will result in a TypeError. CL-USER 3 > (concatenate 'string "abc" 'foo "def")
Error: In a call to LENGTH: FOO (of type SYMBOL) is not of type SEQUENCE.
> There are three ways to obtain a symbol.> Call Symbol()
(make-symbol "FOO")
> Call Symbol.for(string) (find-symbol "FOO")
Other than that symbols in Common Lisp have a package, a value, a function and a property list. Symbols can be interned in a package or not. So-called Keyword symbols are in the package KEYWORD and have itself as the value. :I-AM-A-KEYWORD evaluates to :I-AM-A-KEYWORD.Thanks for posting.
As the article says you can't implicitly convert a symbol's description to string. Symbol is now the only native object in JavaScript that has this behavior.
var str = "something" + "str"; // Works
var num = "something" + 5; // Works
var func = "something" + function () { }; // Works
var obj = "something" + { some: "test" }; // Works
var bool = "something" + true; // Works
var dt = "something" + Date.now(); // Works
var und = "something" + undefined; // Works
var nul = "something" + null; // Works
var nan = "something" + NaN; // Works
var sym = "something" + Symbol("test"); // Throws TypeError
Another thing, which is more of a style thing in my opinion, is you can actually define a property with a Symbol which just seems awkward to me. I mean sure you can use it as a property by design so why wouldn't you be able to use defineProperty? I always felt those should be public types of properties where you can add additional logic where necessary.
var obj = { };
Object.defineProperty(obj, Symbol("MyProp"), {
get: function () { return 15; }
});I feel like almost the same thing with Symbol could be accomplished with a simple UUID generator. It's a neat little thing it just feels awkward to me with how JavaScript works.
Convenient yes, a good idea, no.
> Other code using for-in or Object.keys() may stumble over the property you created.
> The standard committee may decide to add an .isMoving() method to all elements. Then you’re really hosed!
So I dunno, maybe don't stash properties into an object that doesn't belong to you? It's this sort of thing that makes me hate the culture around JavaScript. Hacks upon hacks upon hacks just to save a little effort.
I think this sentence has an editing mistake in it:
It’s simply a property whose name is not a symbol rather than a string.
I think that the "not" shouldn't be there, the double negation makes the sentence fail to parse for me at least (ObCaveat: not a native speaker).Probably the most interesting use I've found for Symbols so far is to detect if an object / function was created by a specific factory - https://gist.github.com/yoshuawuyts/2bf8d5394e6f995791a0
(It's like Common Lisp symbols limited inside the keyword package)