Metaprogramming in ES6: Symbols and why they're awesome
blog.keithcirkel.co.uk
blog.keithcirkel.co.uk
Compared to other languages like Ruby or Python, JavaScript's metaprogramming features are not yet as advanced - especially when it comes to nifty tools like Operator Overloading, but ES6 is starting to level the playing field.
What isn't metaprogramming now?
This feels very relevant. http://journal.stuffwithstuff.com/2013/07/18/javascript-isnt...
In a very narrow hay of "has", as in "ES2015 the spec has it, but no JS runtime implements it yet": http://kangax.github.io/compat-table/es6/#proper_tail_calls_...
I'm not trying to be a contrarian. It's just that i see lots of JS developers excited about superfluous things like class syntax or symbols, whereas real game changing additions like proper tail calls seem to pass by unnoticed, and unimplemented by JS runtimes :(
function x() { return x(); }
(define (foo) (foo))
(foo)
The main problem is still that Chrome and Firefox don't support tail call elimination. Babel (6to5) and Traceur do.
A couple quotable lines from the article I have to throw out there are:
> One day, Netscape woke up from a truly epic bender to discover it had jammed a scripting language onto the web and millions of people were using it. Literally none of them liked it. Not one.
> Lots of programmers believe JavaScript is “basically” Scheme because it gives them something they want to believe: that the language they choose to use has some cachet and they don’t have to feel bad about it anymore.
The main difference: Lisp has simple printed representations for interned, uninterned and keyword symbols.
CL-USER 23 > (let ((color-interned-symbols ' (yellow green red))
(color-uninterned-symbols '(#:yellow #:green #:red))
(color-keyword-symbols '( :yellow :green :red)))
(list color-interned-symbols
color-uninterned-symbols
color-keyword-symbols))
((YELLOW GREEN RED) (#:YELLOW #:GREEN #:RED) (:YELLOW :GREEN :RED))
Lisp also has packages for namespaces of symbols.Here you can learn more about computing with symbols, in Lisp:
In any case, I think the book parent is referring to: http://www.amazon.com/Common-LISP-Introduction-Computation-E...
There's history of using foo/bar/baz in examples. So it's a very quick way to signal to the reader, "What this is isn't the important part. The meat of the discussion isn't in this; he crux of it lies elsewhere," and that's a pretty important thing.
There's a cost in using "real" examples. There's a cost to you the author in coming up with them, and then there's the cost to the reader who has to unpack the domain-specific concepts in the example you're synthesizing and disentangle it from what you're actually trying to demonstrate.
Do use foo and bar whenever possible.
Does anybody have any insight on whether my interpretation here is correct?
Global flags always represent information, be it to the people who code them up or attackers who leverage their existence.
The only thing I can think of offhand: time the execution of Symbol.for. Mostly, this won't be terribly illuminating, because the bulk of the work (hashing input + looking in table) will be the same in both cases, and won't take long. But, assuming the registry is a hash table, what you could do in one script is pollute the registry with enough strings to trigger several hash table rebuilds (which you can detect by outsize results from Symbol.for - you add enough strings to provide a good representative set of timings).
Then another script could detect this by doing the same operation and seeing if no call to Symbol.for took much longer than any other. This gets you 1 bit of information... is that useful?
(Also, I wonder what they do about symbol table exhaustion.)
As for the results, they don't themselves hold any extra information, I don't think. Regarding Symbol.for: if the table contained the requested symbol already, it will return that symbol. If it didn't, a new symbol will be added, and returned. These are the only two options, and the caller has no way of knowing which was taken.
And regarding Symbol.keyFor: if the input was previously returned by Symbol.for, returns true. And if not, returns false. Neither tells you anything because the caller can only have acquired the symbol by doing one of these two operations itself, meaning it isn't getting any information that it didn't in theory have already.
Think of `Symbol.for("foo")` as if it were the string "foo". The string "foo" is also global, when passed across iframe boundaries it still retains its meaning. One can use this string on either side. Using it doesn't observably instantiate some global flag, though internally there may be interning and whatnot. Similarly, using Symbol.for("foo") doesn't instantiate any flag, observably.
https://technet.microsoft.com/en-us/library/cc781906(v=ws.10...
You can't determine if a global symbol is being used by another frame. They just ... exist.
> the only way to get the Symbols within an Object
> is Object.getOwnPropertySymbols
Also, Reflect.getOwnKeys.var foo = Symbol('foo')
over
var foo = Symbol()
Edit: now it's back up online.
Any examples of using symbols for variants or flyweights ?
When subclassing, what is the advantage of [Symbol.toStringTag] getter over the toString() method override? Is it just another way to do the same thing?
See zipolupu's comment https://news.ycombinator.com/item?id=9790181
The article also says:
> When you see code like rho == lho it could be converted into rho[Symbol.isAbstractEqual](lho), allowing classes to override what == means to them.
While there's not any technical error here (the examples follow proper alpha-conversion), the "l" and "r" in lho and rho stand for "left" and "right", respectively, so they should be switched.
In the Symbol.match example, "return [find];" should be... "return [index];"?